从数据库中读取用户的认证信息,进行授权认证
相关类及接口
ReactiveUserDetailsService:根据用户名读取用户信息
public interface ReactiveUserDetailsService {
Mono findByUsername(String var1);
}
MapReactiveUserDetailsService:内存中存储用户信息
public class MapReactiveUserDetailsService implements ReactiveUserDetailsService, ReactiveUserDetailsPasswordService {
private final Map users;
public MapReactiveUserDetailsService(Map users) {
this.users = users;
}
public MapReactiveUserDetailsService(UserDetails... users) {
this((Collection)Arrays.asList(users));
}
public MapReactiveUserDetailsService(Collection users) {
Assert.notEmpty(users, "users cannot be null or empty");
this.users = new ConcurrentHashMap();
Iterator var2 = users.iterator();
while(var2.hasNext()) {
UserDetails user = (UserDetails)var2.next();
this.users.put(this.getKey(user.getUsername()), user);
}
}
public Mono findByUsername(String username) {
String key = this.getKey(username);
UserDetails result = (UserDetails)this.users.get(key);
return result == null ? Mono.empty() : Mono.just(User.withUserDetails(result).build());
}
public Mono updatePassword(UserDetails user, String newPassword) {
return Mono.just(user).map((u) -> {
return User.withUserDetails(u).password(newPassword).build();
}).doOnNext((u) -> {
String key = this.getKey(user.getUsername());
this.users.put(key, u);
});
}
private String getKey(String username) {
return username.toLowerCase();
}
}
UserDetails:用户认证信息接口
public interface UserDetails extends Serializable {
Collection extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
User:UserDetails接口实现类
public class User implements UserDetails, CredentialsContainer {
private static final long serialVersionUID = 530L;
private static final Log logger = LogFactory.getLog(User.class);
private String password;
private final String username;
private final Set authorities;
private final boolean accountNonExpired;
private final boolean accountNonLocked;
private final boolean credentialsNonExpired;
private final boolean enabled;
**************
构造函数
public User(String username, String password, Collection extends GrantedAuthority> authorities) {
public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection extends GrantedAuthority> authorities) {
**************
普通方法
public Collection getAuthorities() {
public String getPassword() {
public String getUsername() {
public boolean isEnabled() {
public boolean isAccountNonExpired() {
public boolean isAccountNonLocked() {
public boolean isCredentialsNonExpired() {
public void eraseCredentials() {
private static SortedSet sortAuthorities(Collection extends GrantedAuthority> authorities) {
public boolean equals(Object rhs) {
public int hashCode() {
public String toString() {
**************
返回内部类:User.UserBuilder
public static User.UserBuilder withUsername(String username) {
return builder().username(username);
}
public static User.UserBuilder builder() {
return new User.UserBuilder();
}
public static User.UserBuilder withUserDetails(UserDetails userDetails) {
**************
内部类:User.UserBuilder
public static class UserBuilder {
private String username;
private String password;
private List authorities;
private boolean accountExpired;
private boolean accountLocked;
private boolean credentialsExpired;
private boolean disabled;
private Function passwordEncoder;
**********
构造方法
private UserBuilder() {
this.passwordEncoder = (password) -> {
return password;
};
}
**********
普通方法
public User.UserBuilder username(String username) {
public User.UserBuilder password(String password) {
public User.UserBuilder passwordEncoder(Function encoder) {
public User.UserBuilder roles(String... roles) {
List authorities = new ArrayList(roles.length);
String[] var3 = roles;
int var4 = roles.length;
for(int var5 = 0; var5 < var4; ++var5) {
String role = var3[var5];
Assert.isTrue(!role.startsWith("ROLE_"), () -> {
return role + " cannot start with ROLE_ (it is automatically added)";
});
authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
}
return this.authorities((Collection)authorities);
}
public User.UserBuilder authorities(GrantedAuthority... authorities) {
return this.authorities((Collection)Arrays.asList(authorities));
}
public User.UserBuilder authorities(Collection extends GrantedAuthority> authorities) {
this.authorities = new ArrayList(authorities);
return this;
}
public User.UserBuilder authorities(String... authorities) {
return this.authorities((Collection)AuthorityUtils.createAuthorityList(authorities));
}
public User.UserBuilder accountExpired(boolean accountExpired) {
public User.UserBuilder accountLocked(boolean accountLocked) {
public User.UserBuilder credentialsExpired(boolean credentialsExpired) {
public User.UserBuilder disabled(boolean disabled) {
public UserDetails build() {
String encodedPassword = (String)this.passwordEncoder.apply(this.password);
return new User(this.username, encodedPassword, !this.disabled, !this.accountExpired, !this.credentialsExpired, !this.accountLocked, this.authorities);
}
}
private static class AuthorityComparator implements Comparator, Serializable {
private static final long serialVersionUID = 530L;
private AuthorityComparator() {
}
public int compare(GrantedAuthority g1, GrantedAuthority g2) {
if (g2.getAuthority() == null) {
return -1;
} else {
return g1.getAuthority() == null ? 1 : g1.getAuthority().compareTo(g2.getAuthority());
}
}
}
}
示例
****************
service 层
CustomReactiveUserDetailsService
@Service
public class CustomReactiveUserDetailsService implements ReactiveUserDetailsService {
@Resource
private UserService userService;
@Resource
private PasswordEncoder passwordEncoder;
@Override
public Mono findByUsername(String s) {
QueryWrapper queryWrapper=new QueryWrapper<>();
queryWrapper.eq("name",s);
User user=userService.getOne(queryWrapper);
UserDetails userDetails= org.springframework.security.core.userdetails.User.builder()
.username(user.getName())
.password(user.getPassword())
.passwordEncoder(passwordEncoder::encode)
.roles(JSONObject.parseArray(user.getRoles(),String.class).toArray(new String[]{}))
.build();
return userDetails == null ? Mono.empty() : Mono.just(org.springframework.security.core.userdetails.User.withUserDetails(userDetails).build());
}
}
WebSecurityConfig
@Configuration
public class WebSecurityConfig {
@Bean
public SecurityWebFilterChain initSecurityWebFilterChain(ServerHttpSecurity http){
http.formLogin().and().authorizeExchange()
.pathMatchers("/hello2").hasAnyRole("user")
.pathMatchers("/**").permitAll();
return http.build();
}
@Bean
public PasswordEncoder initPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
****************
controller 层
UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private PasswordEncoder passwordEncoder;
@Resource
private UserService userService;
@RequestMapping("/add")
public String addUser(){
User user=new User();
user.setName("瓜田李下");
user.setAge(20);
user.setPassword("123456");
List roles=new ArrayList<>();
roles.add("user");
roles.add("admin");
String rolesString=JSONObject.toJSONString(roles);
user.setRoles(rolesString);
userService.save(user);
return "success";
}
}
使用测试
localhost:8080/user/add:向数据库添加认证用户
localhost:8080/hello2
认证通过后,输出:hello 瓜田李下