学习视频教程Spring Security开发REST服务到 4-3 自定义用户认证逻辑

1. 使用security进行用户校验,首先要实现UserDetailsService接口,用于获取用户信息进行校验;

@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		log.info("输入的用户名是:" + username);
		UserModel user = new UserModel();
		user.setUserName(username);
		user.setAge(18);
		user.setPassword("123456");
		log.info("通过业务逻辑得到的用户信息为:" + JSONObject.toJSONString(user));
		String authorityList = "admin,user,root";
		UserDetails userDetail = new User(user.getUserName(), user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(authorityList));
		return userDetail;
	}

2. 在执行的时候,发现出现了以下问题:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

网上百度了一下发现这是由于Spring security5中新增加了加密方式,并把原有的spring security的密码存储格式改了。

去官网查找得知,修改后的密码存储格式为:{id}encodedPassword

 我们只需要对前端传过来的密码进行某种方式加密,就可以了,而官方推荐的是使用bcrypt的加密方式。
 

解决办法如下:在Securty配置类SecurtyConfig(继承 WebSecurityConfigurerAdapter)中修改 配置即可。

简单起见,还有一个也可以解决,使用过期的方法:

    @Bean
	public static PasswordEncoder passwordEncoder() {
		return NoOpPasswordEncoder.getInstance();
	}

之后就看到了正确的结果,当我们输入的密码不是上面指定的“123456”时会报出“坏的凭证”,否则正确执行得到结果。

3. 如果除了严重密码是否正确外,还需要验证用户的其他信息,比如:账号过期、账号锁定、密码过期、账号被删除(逻辑删除或冻结)等,可以修改返回的用户详细信息。

@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		log.info("输入的用户名是:" + username);
		UserModel user = new UserModel();
		user.setUserName(username);
		user.setAge(18);
		user.setPassword("123456");
		user.setAccountNonExpired(false);  //账号没有过期
		user.setAccountNonLocked(true);   //账号没有锁定
		user.setCredentialsNonExpired(true); //密码没有过期
		user.setEnabled(true);  //账号是否可用(没有被删除)
		
		log.info("通过业务逻辑得到的用户信息为:" + JSONObject.toJSONString(user));
		String authorityList = "admin,user,root";
//		UserDetails userDetail = new User(user.getUserName(), user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(authorityList));
		UserDetails userDetail = new User(user.getUserName(), user.getPassword(), 
				user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(),
				AuthorityUtils.commaSeparatedStringToAuthorityList(authorityList));
		
		return userDetail; 
	}

 

4. 密码加密解密方式:

首先定义加密方式:
 

@Bean
public PasswordEncoder passwordEncoder() {
       return new BCryptPasswordEncoder();
}

然后,可以读取业务逻辑中保存的加过密的密码,这里也可以直接使用加密我们密码的方式来得到密文:

//加过密的密码
String encoderPassword = passwordEncoder.encode(user.getPassword());

最后,在返回的用户详细信息中使用这个加过密的密文即可:

log.info("加密后的密码为:" + encoderPassword);
UserDetails userDetail = new User(user.getUserName(), encoderPassword, 
				user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(),
				AuthorityUtils.commaSeparatedStringToAuthorityList(authorityList));
		
return userDetail; 

另外,说明一点是:用BCryptPasswordEncoder执行过加密的密文,每次结果是不一样的,是加过盐的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值