在Spring安全5中,接口显示为ReactiveUserDetailsService。
现在我的问题是如何使用以下方法实现UserDetailsService:
我有(用户存储在内存中)
@Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder().username("test").password("password").roles("USER").build();
UserDetails admin = User.withDefaultPasswordEncoder().username("admin").password("admin").roles("USER", "ADMIN").build();
return new MapReactiveUserDetailsService(user, admin);
}
我想要的是什么:
@Document(collection = "user")
public class User implements UserDetails {
@Id
private Long id;
private LocalDate createdAt;
private String username;
private String password;
private boolean accountNonLocker;
private boolean enabled;
@DBRef
private List<GrantedAuthority> grantedAuthorities;
//getters and setters
}
@Component
public class SecUserDetailsService implements ReactiveUserDetailsService {
}
我不知道如何实现它。没有在网上找到任何资源。
答案 0 :(得分:2)
已经找到了解决方案:
UserDetails
类中实现UseAccount
接口并创建实现GrantedAuthority
接口的Role类:
<强>角色强>
@Data
@Document
public class Role implements GrantedAuthority {
@Id
private String id;
@Override
public String getAuthority() {
return id;
}
}
<强> UseAcount 强>
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document
public class UserAccount implements UserDetails {
@Id
private String id;
private String username;
private String password;
private String firstName;
private String lastName;
private String idnp;
@Email
private String email;
@Builder.Default()
private boolean active = true;
@Builder.Default()
@DBRef
private List<Role> roles = new ArrayList<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return active;
}
@Override
public boolean isAccountNonLocked() {
return active;
}
@Override
public boolean isCredentialsNonExpired() {
return active;
}
@Override
public boolean isEnabled() {
return active;
}
@Override
public String getName() {
return firstName + " " + lastName;
}
}
@Configuration
@EnableWebFluxSecurity
public class SecurityConfiguration {
@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
return http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/login", "/logout").permitAll()
.pathMatchers("/i18n/**",
"/css/**",
"/fonts/**",
"/icons-reference/**",
"/img/**",
"/js/**",
"/vendor/**").permitAll()
.anyExchange()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.and()
.logout()
.logoutUrl("/logout")
.and()
.build();
}
//in case you want to encrypt password
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@Component
public class SecUserDetailsService implements ReactiveUserDetailsService {
@Autowired
public ReactiveUserAccountRepository reactiveUserAccountRepository;
@Override
public Mono<UserDetails> findByUsername(String username) {
Mono<UserAccount> data = reactiveUserAccountRepository.findByUsername(username);
return data.cast(UserDetails.class);
}
}
答案 1 :(得分:0)
您需要实现ReactiveUserDetailsService接口:
public interface UserRepository extends ReactiveCrudRepository<User, ObjectId>, ReactiveUserDetailsService {
Mono<UserDetails> findByUsername(String username);
}
使用UserDetailsRepositoryAuthenticationManager而不是MapReactiveUserDetailsService:
@Bean
public ReactiveAuthenticationManager authenticationManager(UserRepository userRepository) {
return new UserDetailsRepositoryReactiveAuthenticationManager(userRepository);
}