spring-security使用-自定义数据源(二) 部分源码 自定义UserDetailsService

1.前面一demo的配置是基于内存数据源配置,但是再实际应用中我们都是查库

   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /**
         *  inMemoryAuthentication 开启在内存中定义用户
         *  多个用户通过and隔开
         */
        auth.inMemoryAuthentication()
                .withUser("liqiang").password("liqiang").roles("admin")
                 .and()
                .withUser("admin").password("admin").roles("admin");
    }

2.查看具体方法org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder#inMemoryAuthentication

   public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication() throws Exception {
        return (InMemoryUserDetailsManagerConfigurer)this.apply(new InMemoryUserDetailsManagerConfigurer());
    }
 private <C extends UserDetailsAwareConfigurer<AuthenticationManagerBuilder, ? extends UserDetailsService>> C apply(C configurer) throws Exception {
        //这里实际拿到对应的Configer的的UserDetailsService
        this.defaultUserDetailsService = configurer.getUserDetailsService();
        //这里先不管
        return (UserDetailsAwareConfigurer)super.apply(configurer);
    }

3.查看UserDetailsService接口定义

 public interface UserDetailsService {
        //根据用户名查询用户信息
        UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
    }

4.UserDetails接口定义

public class UserDetails {
    /**
     * 用户的权限信息
     * @return
     */
    Collection<? extends GrantedAuthority> getAuthorities();

    /**
     * 用户密码
     * @return
     */
    String getPassword();
    /***
     * 用户名
     * @return
     */
    String getUsername();
    /**
     *表示帐号是否未过期
     * @return
     */
    boolean isAccountNonExpired();
    /**
     *表示帐号是否未锁定
     * @return
     */
    boolean isAccountNonLocked();
    /**
     * 表示登录凭据是否未过期
     * @return
     */
    boolean isCredentialsNonExpired();
    /**
     * 是否启用
     * @return
     */
    boolean isEnabled();
}

自定义UserDetailsService

1.先自定义封装查询用户信息的dto

public class UserInfoDto implements UserDetails {
    private List<?extends GrantedAuthority> authorities;
    private String password;
    private String username;

    public void setAuthorities(List<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * 用户的权限信息
     * @return
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }
    /**
     * 用户密码
     * @return
     */
    @Override
    public String getPassword() {
        return password;
    }
    /***
     * 用户名
     * @return
     */
    @Override
    public String getUsername() {
        return username;
    }
    /**
     *表示帐号是否未过期
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     *表示帐号是否未锁定
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    /**
     * 表示登录凭据是否未过期
     * @return
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /**
     * 是否启用
     * @return
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

2.实现自定义UserDetailService

@Service
public class UserService  implements UserDetailsService {
    /**
     * 根据用户名查询用户信息
     * @param s
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //模拟查询db
        System.out.println("模拟查询db");
        //将db查询结果封装返回
        UserInfoDto userInfoDto=new UserInfoDto();
        userInfoDto.setUsername(s);
        userInfoDto.setPassword("22222");
//权限标识 userInfoDto.setAuthorities(
null); return userInfoDto; } }

3.设置自定义的userServuce

 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //设置自定义的userDetailService
        auth.userDetailsService(userService);
    }