Spring security的SecurityConfig配置时 userDetailsService报错如何解决?

报错信息

在这里插入图片描述

‘userDetailsService(T)’ in ‘org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder’ cannot be applied to ‘(com.user_service.service.IUsersService)’

原因

这个错误是因为在 SecurityConfig 配置中,AuthenticationManagerBuilderuserDetailsService 方法期待的是实现了 UserDetailsService 接口的类,而你可能传递的是 IUsersService,而它并没有实现 UserDetailsService 接口。

解决方案

要解决这个问题,你有以下几种方式:

1. 实现 UserDetailsService 接口

首先,你需要让 IUsersService 实现 UserDetailsService 接口,以便它能够被 AuthenticationManagerBuilder 使用。

修改 IUsersService 接口和实现类

你可以扩展 IUsersService 接口,使其实现 UserDetailsService,例如:

import org.springframework.security.core.userdetails.UserDetailsService;

public interface IUsersService extends IService<Users>, UserDetailsService {
    // 其他方法声明
}

然后在 UsersServiceImpl 类中实现 UserDetailsServiceloadUserByUsername 方法:

import com.user_service.entity.Users;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Users user = this.getOne(new QueryWrapper<Users>().eq("username", username));
        if (user == null) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                new ArrayList<>());
    }
}

这样,IUsersService 就实现了 UserDetailsService,可以在 SecurityConfig 中使用。

2. 修改 SecurityConfig

SecurityConfig 中,现在可以注入 IUsersService,并将其作为 userDetailsService 使用:

import com.user_service.service.IUsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private IUsersService usersService;

    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(usersService) // 这里传入 usersService
                .passwordEncoder(passwordEncoder())
                .and()
                .build();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/auth/login", "/auth/register").permitAll()
                .anyRequest().authenticated()
            )
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .addFilterBefore(new JwtAuthenticationFilter(jwtTokenUtil, signatureUtil, usersService), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

3. 其他注意事项

  • 如果你使用了自定义的 UserDetails 实现,确保在 UsersServiceImpl 中的 loadUserByUsername 方法返回了正确的 UserDetails 实例。
  • 如果用户的角色或权限信息也存储在 Users 实体中,你需要在 loadUserByUsername 方法中将这些信息转换为 UserDetails 对象。

通过这些修改,你应该能够将 IUsersService 作为 UserDetailsService 使用,并解决上述错误。

仅为个人知识分享及开发中遇到的问题总结,
希望对你有所帮助,若有问题欢迎指正~😊

  • 15
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值