1.遇到这个报错大概都是因为在实现UserDetailService接口,执行查库操作发现有null值
2.确定null值的字段
在测试类中
//注入Mapper
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
//调用方法
System.out.println(userMapper.getUserByPhoneNumber("1"));
}
//打印的结果
User{phoneNumber='null', password='1'}
发现数据库的字段phoneNumber为空值,能查出password,但phoneNumber找不到。
最后了解发现,在数据库表中的字段带有_,比如phone_number,在实体类中,如果你使用小驼峰需要在Yaml这样配置开启小驼峰规则
mybatis:
configuration:
map-underscore-to-camel-case: true
还有一步就是在Mapper中加入
@Select("select phone_number,password from customer where phone_number=#{phoneNumber}")
@Result(column = "phone_number",property = "phoneNumber",jdbcType = JdbcType.VARCHAR)
Customer getUserByPhoneNumber(String phoneNumber);
3.More
在security中加入自己的验证规则可以实现AuthenticationProvide接口
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserDetailsService userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SmsCodeAuthenticationToken smsCodeAuthenticationToken = (SmsCodeAuthenticationToken) authentication;
/**
* 我的用户实体类实现了UserDetailer接口,userDetailsService也有我自己的实现类。
*所有要使用security框架,进行查库操作用户实体类和XXXUserDetailService需要实现相应的接口才能把自己的规则加入到Security中
*/
UserDetails user = userDetailsService.loadUserByUsername((String)smsCodeAuthenticationToken.getPrincipal());
//用户user为空说明,数据库中查不到
if(user == null){
throw new InternalAuthenticationServiceException("用户不存在");
}
//下面是验证在数据库中查到的密码和用户输入的密码是否相同
if(!new BCryptPasswordEncoder().matches(smsCodeAuthenticationToken.getCredentials().toString(),user.getPassword())){
throw new BadCredentialsException("密码不正确");
}
//进入到SmsCodeAuthenticationToken类,将用户和用户权限存到SmsCodeAuthenticationToken对象中
SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user,user.getAuthorities());
authenticationResult.setDetails(smsCodeAuthenticationToken.getDetails());
return authenticationResult;
}
@Override
public boolean supports(Class<?> aClass) {
return SmsCodeAuthenticationToken.class.isAssignableFrom(aClass);
}
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
}
SmsCodeAuthenticationToken类
public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final Object principal;
private Object credentials;
public SmsCodeAuthenticationToken(String mobile,String password) {
super(null);
this.principal = mobile;
this.credentials=password;
setAuthenticated(false);
}
public SmsCodeAuthenticationToken(Object principal,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
super.setAuthenticated(true); // must use super, as we override
}
public Object getCredentials() {
return this.credentials;
}
public Object getPrincipal() {
return this.principal;
}
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_44932487/article/details/116559664
内容来源于网络,如有侵权,请联系作者删除!