spring security webflux 数据库存储认证用户


spring security webflux 数据库存储认证用户

 

从数据库中读取用户的认证信息,进行授权认证

 

 

********************

相关类及接口

 

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 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 authorities) {
    public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection 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 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 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

                        spring security webflux 数据库存储认证用户_第1张图片

认证通过后,输出:hello 瓜田李下

 

 

你可能感兴趣的:(spring security webflux 数据库存储认证用户)