spring-security 用户名错了也能进入

前言

最近在跟着尚硅谷的视频看spring-security框架的教程,视频传送门
在讲认证的时候,老师讲了三种方式

  • 在application.yml或application.properties配置文件中配置用户名和密码
  • 通过配置类配置用户名和密码
  • 通过实现org.springframework.security.core.userdetails.UserDetailsService接口, 从数据库中查询用户,从而确定是否能进入

前两种直接写死的情况,在正常的项目中用得可能比较少,用得比较多的可能还是第三种,从数据库中查询的方式,

视频中老师为了演示这种功能,起先没有从数据库中读取,而是在实现接口的地方直接new了一个org.springframework.security.core.userdetails.User对象,表示这个用户能够登陆到系统

但是问题来了:
我发现,这样写之后,只要密码对了,用户名无论怎么输,都是能进入到系统中,我看视频中好多小伙伴也发弹幕说有这样的情况。老师好像没有发现这个情况,或者是觉得这个问题很简单,所以压根没有提。

分析

我当时就很懵,然后打了个断点调式,恍然大悟,
我用户名输入的1111,密码是正确的
断点图
我们在这个loadUserByUsername方法中,做了什么事情?返回了一个设置了用户名、密码、权限集合的org.springframework.security.core.userdetails.User对象,所以我们理所当然的认为:应该用户名和密码都与我们设置的相匹配,才能进入到系统。但我们仔细看这个方法的名称:loadUserByUsername,见名知意,这个方法是通过用户名加载用户,结合我们的断点,方法的参数String,的确是将我们的用户名传过来了。

那这又能说明什么呢?说明spring-security的登录判断逻辑和我们常理思考的不一样,我们常理认为,登录是通过用户名和密码去查询数据库,能查出来,就表示能登录,否则不能。而spring-security是怎么做的呢?他是让我们通过用户名去数据库中查询用户,然后把查询出来的用户信息封装成他要求的对象(rg.springframework.security.core.userdetails.User),返回给他,他再去比对密码。按照正常情况,这样做是不会出问题的,我们做用户名的比对(根据用户名去数据控中查),spring-security做密码的比对。但是现在情况是:我们没有根据用户名去查询数据,而是直接返回给了spring-security一个我们自己new的一个用户。所以就是说我们没有做用户名的比对,spring-security又是只做的密码比对,所以无论用户名是什么,只要密码正确,都能进入到系统。

不知道我描述清楚了没有,如果非要用户名和密码都正确的话,我们可以自己验证一下用户名
验证用户名

这样当我再次输入其他用户名时
用户名输入错误

总结

其实这个问题简单来说就是:spring-security把用户名判断的工作交给了使用者,他自己只做密码判断,使用者在通过用户名去数据库中查询用户时,就是在判断用户名。恰好我们没有通过数据库查询,而且我们没有意识到,spring-security把用户名判断的工作交给了我们,所以就出现了这个问题。

如果spring-security明确的告诉了我们,要我们自己判断用户名,那我们肯定知道判断用户名。但是他并没有,而我们也没有意识到:让我们通过用户名查询用户,其实就是在让我们判断用户名。

我们经常看视频学东西,跟着视频敲,还是缺少了自己的思考。其实根据loadUserByUsername这个方法名字,我们就应该意识到。

自己分析的,哪里说得不对,还请指正
  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值