一、问题描述
无法登陆,登录报错
二、问题排查
这个报错,我们可以从spring security的源码中看到
很明显,就是在创建security的user对象的时候,username参数为null或为空字符串/password为空
那哪里会创建security的user对象呢?
在security的userdetailsservice类的实现类中创建了security的对象
public class myuserdetailsservice implements userdetailsservice {
// 部分代码略
public userdetails loaduserbyusername(string username) {
// 部分代码略
return new org.springframework.security.core.userdetails.user(
username,
password, // 【注意】这个password是在数据库根据username查的
true,
true,
true,
true,
roleconfig.getauthorities(xxx)
);
}
}
在这里我们可以看到要么username的问题,要么password的问题。
三、解决思路
在你项目中找到哪里创建了org.springframework.security.core.userdetails.user对象,然后排查username和password为空的情况,数据库限制、代码限制等方式,限制这两个字段不为空。
四、补充
简单解释security是如何做密码校验的,帮助排查密码是否为null和其它关于密码检验失败的问题。
public class jwtloginfilter extends abstractauthenticationprocessingfilter {
@override
public authentication attemptauthentication(httpservletrequest req, httpservletresponse res) throws authenticationexception, ioexception {
// 部分代码省略
return getauthenticationmanager().authenticate(
new usernamepasswordauthenticationtoken(
username,
password // 【注意】这个password是登陆时传过来的
)
);
}
@override
protected void successfulauthentication(httpservletrequest req,
httpservletresponse res,
filterchain chain,
authentication auth) throws ioexception {
// 部分代码省略
}
@override
protected void unsuccessfulauthentication(httpservletrequest req,
httpservletresponse res,
authenticationexception failed) throws ioexception {
// 部分代码省略
}
// 部分代码省略
}
在attemptauthentication方法中,最后return的这一步,会做2个操作
(1)携带username这参数,调用问题排查中讲到的loaduserbyusername方法,加载数据库信息到security的user对象中。
(2)拿参数password【登陆时前端传来的】按照配置的或者默认的加密方式加密后与上一步user中的passward【数据库查的】进行比较,相同则调用successfulauthentication方法,失败调unsuccessfulauthentication方法,我们可以自定义这两个方法,来处理成功和失败要做的操作。
最后修改时间:2021-11-12 22:23:50
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。