文章目录
- 报错信息
- 原因
- 解决方案
- 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 {
@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
使用,并解决上述错误。
仅为个人知识分享及开发中遇到的问题总结,
希望对你有所帮助,若有问题欢迎指正~😊