如何在Spring Boot中通过配置文件动态配置带ID的UserDetailsService实现Basic认证
Spring Boot 多用户动态认证配置(自定义User含ID字段)
1. 编写application.yml多用户配置
先在配置文件中用数组格式定义所有用户的信息,注意密码必须是加密后的字符串,并添加加密方式前缀(比如{bcrypt}):
app: users: - username: admin password: '{bcrypt}$2a$10$Z8HxQx9eK7L5yW4v3u2t1sR0pO9i8u7y6t5r4e3w2q1a0s9d8f7g6h5j4k3l2' id: 1 roles: ADMIN,USER - username: normal_user password: '{bcrypt}$2a$10$A1b2C3d4E5f6G7h8I9j0kL1m2N3n4O5p6Q7r8S9t0U1v2W3x4Y5z6' id: 2 roles: USER
2. 创建配置映射类绑定用户数据
用Spring Boot的@ConfigurationProperties把配置文件中的用户列表绑定到Java对象,方便后续读取:
@Data @ConfigurationProperties(prefix = "app") @Component // 或者在启动类加@EnableConfigurationProperties(AppUserProperties.class) public class AppUserProperties { private List<AppUser> users; @Data public static class AppUser { private String username; private String password; private Long id; private String roles; } }
3. 实现自定义User类(继承UserDetails)
扩展Spring Security的UserDetails接口,加入自定义的id字段,并实现接口要求的所有方法:
@Data public class CustomUser implements UserDetails { private Long id; private String username; private String password; private Collection<? extends GrantedAuthority> authorities; public CustomUser(Long id, String username, String password, Collection<? extends GrantedAuthority> authorities) { this.id = id; this.username = username; this.password = password; this.authorities = authorities; } // 以下为UserDetails接口默认实现,可根据业务需求调整 @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
4. 实现自定义UserDetailsService
注入刚才的配置映射类,在loadUserByUsername方法中从配置列表中查找用户,转换为自定义的CustomUser对象:
@Service public class CustomUserDetailsService implements UserDetailsService { private final AppUserProperties appUserProperties; // 构造方法注入(推荐使用构造注入而非@Autowired) public CustomUserDetailsService(AppUserProperties appUserProperties) { this.appUserProperties = appUserProperties; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 从配置的用户列表中匹配用户名 AppUserProperties.AppUser matchedUser = appUserProperties.getUsers().stream() .filter(user -> user.getUsername().equals(username)) .findFirst() .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username)); // 将角色字符串转换为GrantedAuthority集合 Collection<GrantedAuthority> authorities = Arrays.stream(matchedUser.getRoles().split(",")) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); // 返回包含ID字段的自定义用户对象 return new CustomUser(matchedUser.getId(), matchedUser.getUsername(), matchedUser.getPassword(), authorities); } }
5. 配置Spring Security基础认证
配置密码编码器和安全过滤链,启用HTTP基础认证:
@Configuration @EnableWebSecurity public class SecurityConfig { // 配置BCrypt密码编码器,对应配置文件中的加密方式 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() // 所有请求都需要认证 ) .httpBasic(Customizer.withDefaults()); // 启用HTTP基础认证 return http.build(); } }
关键注意点
- 密码必须加密:可以通过
new BCryptPasswordEncoder().encode("你的明文密码")生成加密后的字符串,再填入配置文件 - 配置文件密码前缀:必须添加
{bcrypt}前缀,Spring Security会根据前缀识别对应的密码编码器 - 自定义字段扩展:如果需要添加更多用户属性,只需在
AppUser和CustomUser中新增对应字段即可
内容的提问来源于stack exchange,提问作者sonic boom
相关产品推荐
相关产品推荐

