Spring Security用数据库信息做认证|学习笔记

简介: 快速学习 Spring Security 用数据库信息做认证

开发者学堂课程【Spring Security知识精讲与实战演示(一):Spring Security用数据库信息做认证】学习笔记与课程紧密联系,让用户快速学习知识

课程地址https://developer.aliyun.com/learning/course/730/detail/13038


Spring Security 用数据库信息做认证

 

使用自己数据库的信息来完成论证,用我们自己数据库中用户的用户名和密码来完成认证。经过上面业务流程的分析,我们可以得知 Spring Security 只认识叫Userdetailservice 的业务,可以找到 Userdetailservice。

image.png

但是,需要注意,我们自己写的 UserService ,Spring Security 是不认识的,若我们想让它知道我们的业务逻辑,我需要用到它的UserService,但是我们已经有了一个,我们可以继承,我们把 UserDetailsService 粘贴复制在 extends 后,继承过来后,我们可以说我们自己的 UserService 对象已经是它要求的 UserService 的类型。

image.png

因为我继承了它,所以它里面有的功能我也有,所以认识了它也就认识了我。在UserServicelmpl 中有一个就报错了,因为刚才我们有一个接口方法重新实验。

此时,进行实验这个方法首先说参数,username 是用户在浏览器输入的用户名。因为当前的方法是 Spring Security 提供的,它与数据库是无关系的,所以它是浏览器输入的用户名。UserDetails 是 Spring Security 自己的用户对象,就可以写上认证业务。原来的认证是我们用用户名和密码一起查询出来的对象,但是此时他只给了我们用户名,我们无法查出用户。

此时需要注意,在这里面可以换一种思路。有了用户名,可以直接查询出自己的数据库中的用户对象,查询到之后,我们给他转成用 Spring Security 户对象就可以了,所以说就按照这样的思路来做。

第一步,要根据用户名做查询,即 Userdao.findByName(username),在 ctrlout v就显示出 sysUser,就会有同学疑惑,username 不是主键,为什么返回的是一个对象,而不是一个集合。

在实际公司中,我们要注意后台管理系统,能登录后台管理系统的人是非常有限的,也就是我们这里边的用户数量是非常有限的,而这里边的用户我们在添加的时候我们要注意,不要让它重复就可以了,但是我们还是要做一部安全判断。可以这么来做,填写 try,catch(Exception e),就可以把//根据用户名做查询 SysUser sysUser = userDao. findByName (username)return null 这段代码放在 try 里面来,放到这里面之后要注意一个问题,即如果异常怎么办。

首先我们把异常打印出来,让人知道做了什么异常,当然我们将来可以写一个自定义的异常,例如我们在这里写一个,用户名不唯一,我们可以写return null,Spring Security认为return null是认证失败。只要我们填写return null,它就认为我们认证失败。我们走到SysUser sysUser = userDao. findByName (username)这一步不一定查出东西,即有可能用户名输错,查询不到这个用户,此时,我们查出分是null,即sysUser==null,如果等于null,用户名就写错了,很显然return null就告诉Spring Security认证错误。只要没有走到if(sysUser==null) return null这一步,一定查出来有且唯一只有一个用户对象。

但是需要注意,不能把sysUser这个对象直接返,因为这个对象并不是Spring Security要的对象,它要的对象是他自己的,需要有一个它自己的对象,在UserDetails userDetails=new,我们可以看一个,点击ctrl h,这是接口,new不可行,但是下边User有实验了。我们可以用这个实验来用,我们在new后输入User(),但是它报的是错误,意思是,此时我们new出来之后,这个对象并没有给他传构造参数,换句话来说,User里面是没有构造的方法。

点击User进入后里边有两个方法,第一个有三个参数,第二个比第一个多了四个boolean,这四个boolesn其实是在判断当前用户是否有效。即我们暂时可以先不考虑这四个属性,我们直接用简单的先把认证流程走通。

image.png

点击Collection<?,进入之后,第一个是username,第二个是password,第三个是authorities,刚才在梳理认证流程的时候说认证最后的时候我们必须要把权限给它,不给它就会报错了。换句话来说,authorities是认证通过后用户下所有的角色集合。

首先在User()中填写username,严格来说应该填写sysUser.getUsername(),但是浏览器的用户名和数据库中的用户名两个用户名是一样,但是如果不一致,是走不到这一步的。接着补齐,即sysUser.getUsername(),sysUser.getPassword(),sysUser.getPassword()密码是数据库中查询出来的密码。我们都知道在浏览器输入的无论是用户名还是密码,已经告诉它了,它封装到一个叫userpasswordtoken中。所以在这里边我们直接告诉它数据库中的密码就可以,但是我们要注意,密码这里是不对的。一开始这里有一个叫noop后面的springsecurity会认为是原文。正常情况下,在表数据中的密码不会填写123,我们直接把原文存进来,只要是登录数据库的人都能看到我们的密码,那这个就不叫做密码了,因为我们都知道。

此时需要注意,暂时只能写123,然后想加密的时候我们就把它给处理掉,即我们这里暂时写的是原文,我们在用的时候也得用原文,但是如果我们不写这个noop,那么springsecurity会认为这是个秘文,就认为数据库里面存的密文,但是我们现在还没有存密文,所以现在我们要在 sysUser.getPassword 前加上 noop。

我们知道还有一个参数,这个参数比较复杂,拎出来单独封装。我们要注意,我们把Collection<? extends GrantedAuthority> authorities剪切到// {noop)后面的密码,springsecurity会认为是原文这句话的上边。把鼠标放在Collection上就出现了java.util,我们把Collection直接修改成List,List相较于Collection功能更强大。即我们可以拿功能强大的是去替代功能弱一点的,但是如果别人要的是List,我们就不能写Collection。即我们写List是没问题的,随便一个对象,只要是GrantedAuthority就可以了。点击GrantedAuthority,进入后,点击ctrl h,出现SimpleGrantedAuthority,是刚才的类型。点击ctrl v进行粘贴复制过去,接着填写List<SimpleGrantedAuthority> authorities = new ArrayList<>()。因为里面是空的,而我们要角色,若没有角色,我们依旧通过不了配置认证信息,所以是不对的。

所以我们需要把当前用户下的角色填写进去。所以把authorities.add(new SimpleGrantedAuthority)(),但是写完之后它还是报错,证明当前又没有构造方法。点击SimpleGrantedAuthority,进入之后,我们会发现,这里面乱糟糟,给了一堆东西,但是代码没多少。带参数的是构造方法,即必须传role这个角色,否则就会报错。它封装很多对象,但是此时有用的就一个方法。即我们提供一个对象,是便于外界去取。

已经得到getAuthority这个角色,返回的是我们赋予它的角色,所以有些对象封装的很完美,但是点进来却很简单。在SimpleGrantedAuthority()从用户中得到角色,把角色动态往括号里添,但是需要注意,现在我们点用户表,点决策表,用户跟角色都有,但是我们点他俩的关联表,是没有数据的,所以我们暂时还不能走这一步,所以我们添的角色是role user,添过来之后我们会发现,我们刚才需要的这个角色是role user,如果不是它,我们还得手动去填别的。当我们手动把角色添进入,这个角色不是动态赋值,无论是谁登录进来都是这个角色。

后期我们再改成动态,因为现在改动态是不能通过的。到此UserDetail封装成功,然后我们把它返回就可以了。但是返回不一定成功,我们要注意,我们给它的密码它自己会判断,因为我们浏览器输的密码已经被它保存了,接下来就会判断我们这两个密码是否一致,一致就认证成功,不一致就认证失败。

接下来,要把spring security认证数据的来源改掉,我们认证的数据现在还是来自于内存,这是不对的,我们把 <security:user-service〉<security:user name="admin" password="{noop}admin”authorities="ROLE_ADMTN”/></security:user-service〉删掉,在 security:authentication-provider 〉中填写userservice-ref"",在引号里填写给 userdetailservice 的对象。当前的对象放在id容器中,我们放在容器中没有起 ID,没有起就是当前类名首字母小写,把UserServiceImpl复制粘贴到引号里。把 U 改成小写,这样就完成了认证流程。

image.png

可以来刷新一下,看看现在这个流程通不通,刷新完之后返回到ITCAST后台管理系统页面,用户名此时不能再填写user,因为这里边是内存中的用户信息,而我们现在已经把内存的那个删除了,现在要写 xiaoming,密码是123,点击登录。

认证通过之后,这个决策是写死的,不能所有人进来都是这一个角色,那这个流程就有问题了。需要进行优化,我们现在要先做一个操作才能退出去优化,否则就登录不上来,就必须手动改数据库了,可以在系统管理处点用户管理,再点击修改角色,接下来我们把ROLE_USER勾上,我们要注意,第一次演示是可以通过的,但是注意看,我们点击保存后,它显示了403,我们注意看这个异常,认证的时候需要csrf认证的token。

找到user-role-add.jsp,在这个页面最上面要加上 Spring security 的动态标签,填上taglib uri="http://www.springframework.org/security/tags"prefix="security"%>,接下来我们就在这个认证的表单内部认证报表,我们需要注意它是post请求,所以它会出这个问题,把security接过来,填写成 security:csrfInput,如下图

image.png

要刷新。要重新登录,名称依旧是写 xiaoming,密码是123,点登录,在系统管理里点击用户管理,继续修改角色,继续点击保存,修改成功。此时我们来看数据库,进行刷新就会有数据,此时我们就可以动态授权。在List(SimpleGrantedAuthority> authorities=new ArrayListo() 后填写上List<SysRole> roles = sysUser. getRoles():for (SysRole role :roles)。再将authorities.add(new SimpleGrantedAuthority( role"ROLE _USER")) 移至上一行,并且将 ROLE _USER 修改成 getRoleName,因为 name 是才是绝人名称,接下来的认证流程动态会议角色写完之后,重新刷新测试。

image.png

需要注意的是,如果此时再测试通过,那我们的认证是彻底做完。我们再次返回登录系统界面,用户名填写 xiaoming,密码是123,点击登录。我们会发现认证成功。

相关文章
|
19天前
|
安全 Java 数据安全/隐私保护
|
3天前
|
Cloud Native 关系型数据库 分布式数据库
数据库性能诊断工具DBdoctor通过阿里云PolarDB产品生态集成认证
DBdoctor(V3.1.0)成功通过阿里云PolarDB分布式版(V2.3)集成认证,展现优秀兼容性和稳定性。此工具是聚好看科技的内核级数据库性能诊断产品,运用eBPF技术诊断SQL执行,提供智能巡检、根因分析和优化建议。最新版V3.1.1增加了对PolarDB-X和OceanBase的支持,以及基于cost的索引诊断功能。PolarDB-X是阿里巴巴的高性能云原生分布式数据库,兼容MySQL生态。用户可通过提供的下载地址、在线试用链接和部署指南体验DBdoctor。
|
4天前
|
安全 Java 数据库连接
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通
|
4天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
13 1
|
14天前
|
XML Java 数据格式
Spring学习__一篇足矣
Spring学习__一篇足矣
Spring学习__一篇足矣
|
14天前
|
安全 数据管理 数据库
数据管理DMS操作报错合集之阿里云DMS控制台上展示出了已经删除的数据库信息,如何解决
数据管理DMS(Data Management Service)是阿里云提供的数据库管理和运维服务,它支持多种数据库类型,包括RDS、PolarDB、MongoDB等。在使用DMS进行数据库操作时,可能会遇到各种报错情况。以下是一些常见的DMS操作报错及其可能的原因与解决措施的合集。
|
17天前
|
Java 数据安全/隐私保护 Sentinel
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
|
18天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
18天前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
|
18天前
|
开发框架 前端开发 安全
Java从入门到精通:2.2.2学习使用Spring框架进行Web应用开发
Java从入门到精通:2.2.2学习使用Spring框架进行Web应用开发