SSM项目中SpringSecurity基于RBAC的登录验证案例
说明
本项目是基于RBAC模型由SSM架构搭建的一个小案例,其中登录模块的认证使用SpringSecurity来完成,本文主要讲解简单使用SpringSecurity,目的在于学习SpringSecurity的使用,
准备阶段
数据库表设计
RBAC的理论概念略去,不明白的小伙伴可以去搜索一下概念,这里就不再展开叙述。
三张主表:
用户表
角色表
资源表
由于用户和角色之间是多对多的关系,因此还需要一张中间表(注意设置外键)。
用户角色表
同理角色和资源也是多对多,也需要一张中间表。
角色资源表
SSM搭建
完成dao层、service层、controller层的编写。不再赘述。
使用SpringSecurity的步骤
一共需要三步
1.导入SpringSecurity的依赖
<!--springsecurity依赖-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.0.1</version>
</dependency>
2.编写spring-security.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不拦截的资源 -->
<security:http pattern="/login.jsp" security="none"/>
<security:http pattern="/failer.jsp" security="none"/>
<security:http pattern="/css/**" security="none"/>
<security:http pattern="/img/**" security="none"/>
<security:http pattern="/plugins/**" security="none"/>
<!--
配置具体的规则
auto-config="true" 不用自己编写登录的页面,框架提供默认登录页面
use-expressions="false" 是否使用SPEL表达式(没学习过)
-->
<security:http auto-config="false" use-expressions="false">
<!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_XXX的角色" -->
<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>
<!-- 定义跳转的具体的页面 -->
<security:form-login
login-page="/login.jsp"
login-processing-url="/login.do"
default-target-url="/index.jsp"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/pages/main.jsp"
/>
<!-- 关闭跨域请求 -->
<security:csrf disabled="true"/>
<!-- 退出,并清空session -->
<security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />
</security:http>
<!-- 切换成数据库中的用户名和密码 -->
<security:authentication-manager>
<!--用于指定service的bean,该service必须继承UserDetailsService,实现可以让service接口继承,让service实现接口-->
<security:authentication-provider user-service-ref="userService">
</security:authentication-provider>
</security:authentication-manager>
</beans>
3.在web.xml文件中加载spring-security.xml并配置filter
<!--加载Security的配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-security.xml</param-value>
</context-param>
<!--过滤器-->
<filter>
<!--名字固定-->
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果上面的代码看的不太明白,没关系,接着往下看,接下来先从大体上理一遍思路,然后最后在看步骤2的配置文件。
思路分析
分析流程
原有的SSM架构下登录操作的流程。
要是使用SpringSecurity实现登录的流程
从图中可以看出来,
1、原有的处理页面提交请求的controller层现在由SpringSecurity的配置文件来完成处理。
2、service层,我们怎么知道是哪个具体的service来调用dao层完成操作呢?
于是出现了一个SpringSecurity提供的UserDetailsService类,我们自己写的service只需要继承UserDetailsService重写其中的一个方法即可。
3、dao层返回的不再是原有的实体类对象,而要返回一个SpringSecurity提供的UserDetails类
因此,我们需要将dao查询到的实体类型转换为UserDetails类型。
我们需要做的
1、spring-security.xml配置文件取代了登录功能的controller,在配置文件中配置登录请求的路径,需要处理service层的bean对象等信息。
2、在登录功能的service层需要继承一个UserDetailsService类,并实现其中的loadUserByUsername()方法。
3、在loadUserByUsername()方法里面调用dao层根据username属性获取用户的方法。
4、在loadUserByUsername内部将获取到的用户类型转为SpringSecurity自带的User类型,传入相关参数,username参数,password参数,和角色参数(可多个角色)。
5、在实现一个拼接角色名称getAuthorList方法。
详细过程见下图
实现:SSM架构中service有接口和实现类,因此我们让用户service接口来继承UserDetailsService,service实现类只需要实现service接口就行。
在IUserService接口中
在UserService实现类中
总结
至此,SSM项目的登录功能验证功能就由SoringSecurity来完成。
待解决的问题:
1、SpringSecurity控制登录,用户成功登录之后的session信息怎么保存,怎么在前端页面上取出session信息?
2、SpringSecurity怎么实现用户密码的加密与解密?
本人持续学习,未完待续。
学习之余,仓促成文,如有不足,还请各位指出,谢谢阅读。