文章目录
- 报错信息
- 原因
- 解决方案
- 1. 实现 `UserDetailsService` 接口
- 修改 `IUsersService` 接口和实现类
- 2. 修改 `SecurityConfig`
- 3. 其他注意事项
报错信息
‘userDetailsService(T)’ in ‘org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder’ cannot be applied to ‘(com.user_service.service.IUsersService)’
原因
这个错误是因为在 SecurityConfig
配置中,AuthenticationManagerBuilder
的 userDetailsService
方法期待的是实现了 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
类中实现 UserDetailsService
的 loadUserByUsername
方法:
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 {@Overridepublic 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 {@Autowiredprivate IUsersService usersService;@Beanpublic AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {return http.getSharedObject(AuthenticationManagerBuilder.class).userDetailsService(usersService) // 这里传入 usersService.passwordEncoder(passwordEncoder()).and().build();}@Beanpublic 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();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}
3. 其他注意事项
- 如果你使用了自定义的
UserDetails
实现,确保在UsersServiceImpl
中的loadUserByUsername
方法返回了正确的UserDetails
实例。 - 如果用户的角色或权限信息也存储在
Users
实体中,你需要在loadUserByUsername
方法中将这些信息转换为UserDetails
对象。
通过这些修改,你应该能够将 IUsersService
作为 UserDetailsService
使用,并解决上述错误。
仅为个人知识分享及开发中遇到的问题总结,
希望对你有所帮助,若有问题欢迎指正~😊