3.自定义用户认证逻辑

我们系统默认登录的用户名默认是:user;而对应的密码是每次服务启动后随机生成的密码。常见的场景是我们的用户应该是从数据库读取的。我们从下面几个方面述说自定义用户认证逻辑。

  • 处理用户信息获取逻辑(从数据库获取) <-----> UserDetailsService
  • 处理用户校验逻辑 <-----> UserDetails
  • 处理密码加密解密 <-----> PasswordEncoder

3.1 处理用户信息获取逻辑(从数据库获取)

用户信息获取逻辑是封装到spring-security里面的UserDetailsService里面有:loadUserByUsername方法

@Component  
public class MyUserDetailsService implements UserDetailsService {  
  
    private Logger logger \= LoggerFactory.getLogger(getClass());  
  @Override  
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
        //返回一个实例对象,我们使用spring-security自带的User  
  logger.info("登录用户名:"+username);  
  //根据用户名密码查询授权    
 return new User(username,"123456", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));  
  }  
}

web端测试:
错误用户名/密码:
59.png

正确用户名/密码:
60.png

3.2 处理用户校验逻辑

用户校验分为两部分:

  1. 密码是否匹配,你只要告诉Spring-Security的密码是多少就可以了。
  2. 其他校验:用户是不是被冻结了。是不是密码过期了。

我们在loadUserByUsername里面返回的是:UserDetails,注意UserDetails

public interface UserDetails extends Serializable {  
    Collection<? extends     GrantedAuthority> getAuthorities();  
  String getPassword();  
  String getUsername();  
  boolean isAccountNonExpired();  //账号是不是过期了
  boolean isAccountNonLocked();  //账户是不是锁定了
 boolean isCredentialsNonExpired(); //密码是否过期了 
 boolean isEnabled();  //用户是不是被假删除了
}

其中7个参数的构造函数:多了4个方法判断结果;

@Component  
public class MyUserDetailsService implements UserDetailsService {  
    private Logger logger = LoggerFactory.getLogger(getClass());  
  @Override  
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
  //返回一个实例对象,我们使用spring-security自带的User  
  logger.info("登录用户名:"+username);  
  //根据用户名查找用户信息  
  //根据查找到的用户信息判断用户是否被冻结:我们用7个参数的构造方法  
  // new User(username,"123456", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"))  
 //创建一个用户被锁定账号  
  UserDetails user = new User(username,"123456", true,true, 
 true,false,  AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));  
 return user;  
  }  
}

前端访问:用户名/密码:Jack/123456
请求的结果为:
61.png
因为我们把构造器的参数:accountNonLocked设置为false
我们改为true即可登录。

3.3 处理密码加密解密

在我们的应用中,不会使用明文的密码保存到数据库,从数据库里面取出来的东西也不是明文的,Spring-security中密码加密解密的是一个新的接口。叫做:PasswordEncoder

//对用户信息进行编码;供用户来调用  
String encode(CharSequence var1);  
//数据库里面代码是否跟传过来的代码匹配  
boolean matches(CharSequence var1, String var2);

我们在WebSecurityConfig配置一个PasswordEncoder类:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public PasswordEncoder  passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /**
     * 定义web安全配置类:覆盖config方法
     * 1.参数为HttpSecurity
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         * 定义了任何请求都需要表单认证
         */
       http.formLogin()//表单登录---指定了身份认证方式
       // http.httpBasic()//http的basic登录
          .and()
          .authorizeRequests()//对请求进行授权
          .anyRequest()//任何请求
          .authenticated();//都需要认证
    }
}

然后我们请求接口:发现报错,原因是我们返回的User的密码是明文的
MyUserDetailsService修改:

@Component
public class MyUserDetailsService implements UserDetailsService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //返回一个实例对象,我们使用spring-security自带的User
        logger.info("登录用户名:"+username);
        //根据用户名查找用户信息
        //根据查找到的用户信息判断用户是否被冻结:我们用7个参数的构造方法
       // new User(username,"123456", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"))
        //创建一个用户被锁定账号
        UserDetails user = new User(username,passwordEncoder.encode("123456"), true,true,
                true,true,
                AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
        return user;
    }
}

startshineye
91 声望26 粉丝

我在规定的时间内,做到了我计划的事情;我自己也变得自信了,对于外界的人跟困难也更加从容了,我已经很强大了。可是如果我在规定时间内,我只有3分钟热度,哎,我不行,我就放弃了,那么这个就是我自己的问题,因为你自己...


引用和评论

0 条评论