Spring security在SSM框架中的使用及分析

1. Spring Security概述

1.1 Spring Security简介

Spring Security 是 Spring 项目组中用来提供安全认证服务的框架。 实际上,在 Spring Boot 出现之前,Spring Security 就已经发展了多年了,但是使用的并不多,安全管理这个领域,一直是 Shiro 的天下。

相对于 Shiro,在 SSM/SSH 中整合 Spring Security 都是比较麻烦的操作,所以,Spring Security 虽然功能比 Shiro 强大,但是使用反而没有 Shiro 多(Shiro 虽然功能没有 Spring Security 多,但是对于大部分项目而言,Shiro 也够用了)。

自从有了 Spring Boot 之后,Spring Boot 对于 Spring Security 提供了 自动化配置方案,可以零配置使用 Spring Security。

因此,一般来说,常见的安全管理技术栈的组合是这样的:

  • SSM + Shiro
  • Spring Boot/Spring Cloud + Spring Security
    (这只是一个推荐的组合而已,如果单纯从技术上来说,无论怎么组合,都是可以运行的)

1.2 安全包括的两个主要操作

安全包括两个主要操作:

  1. “认证”,是为用户建立一个他所声明的主体。主题一般式指用户,设备或可以在你系统中执行动作的其他系统。 通俗讲就是身份校验,即在登录时判断你的用户名和密码是否正确
  2. “授权”,指的是一个用户能否在你的应用中执行某个操作,在到达授权判断之前,身份的主题已经由 身份验证 过程建立了。即指明用户在应用系统中能进行什么操作

这些概念是通用的,不是Spring Security特有的。

1.3 spring security框架在登录时实现安全认证的原理

通常进行登录操作时流程如下:
在这里插入图片描述
使用spring security进行登录认证时流程如下:
在这里插入图片描述
原理: 使用spring security时,不再需要写controller,由spring security框架来完成控制器的功能。同时必须用自己写的 IUserServiceextends spring security提供的一个规范认证方法的接口UserDetailsService,并在其实现类UserServiceImpl中 重写UserDetailsServiceloadUserByUsername方法。spring security的配置文件中有这么一行:
在这里插入图片描述
配置实现了UserDetailsService这一spring security规范的接口的service,即指定拿到用户名和密码之后由哪个service进行处理。在UserServiceImpl类上加注解:
在这里插入图片描述

loadUserByUsername方法的返回值类型是 UserDetails,即service层返回给spring security框架的应该是一个UserDetails 类型的对象,通过查看源码可知,UserDetails是一个接口,它有一个实现类 User,因此service层应该返回一个User类型的对象给spring security框架,这个User类型的对象中封装了当前要进行认证的这个用户的信息。然后由spring security框架底层来判断当前登录用户的用户名和密码是否正确。

而userService调用Dao层之后返回的是一个UserInfo类型的对象(UserInfo是自己定义的用户类),因此需要在userService中将 UserInfo类型的对象 封装成 User类型 的对象。具体实现代码见下面。

2. 在基于SSM框架的权限管理系统中应用Spring Security

2.1 Spring Security使用的基本步骤

2.1.1 在pom.xml文件中导入依赖

在这里插入图片描述

2.1.2 在web.xml文件中配置springSecurityFilterChain

在这里插入图片描述
注意这里的filter-name只能是springSecurityFilterChain,不可以改动

2.1.3 创建spring-security.xml配置文件进行配置

在这里插入图片描述
在这里插入图片描述

2.2 代码中的具体实现——登录认证

2.2.1 IUserService.java

在这里插入图片描述

2.2.2 UserServiceImpl.java

在这里插入图片描述
UserDetails是一个接口,可以认为UserDetails作用是封装当前进行认证的用户信息,但由于其是一个接口,所以我们可以对其进行实现,也可以使用Spring Security提供的一个UserDetails的实现类User来完成操作 。
在User类的构造方法中,authorities参数是一个GrantedAuthority类型的集合,GrantedAuthority是一个接口,它有一个实现类 SimpleGrantedAuthority,SimpleGrantedAuthority类的构造函数的参数是一个List< Role >,即一个角色列表。
User类的部分代码如下:
在这里插入图片描述

2.2.3 IUserDao.java

在这里插入图片描述

2.2.4 IRoleDao.java

在这里插入图片描述

2.2.5 IPermissionDao.java

在这里插入图片描述

2.2.6 实体类部分代码如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 使用spring security实现方法级别的权限控制

在服务器端可以通过Spring security提供的注解对方法来进行权限控制。Spring Security在方法的权限控制上支持三种类型的注解,JSR-250注解、@Secured注解和支持表达式的注解,这三种注解默认都是没有启用的,需要单独通过global-method-security元素的对应属性进行启用 。

在配置文件spring-security.xml 中开启注解:
在这里插入图片描述

2.3.1 JSR250注解

(1)@RolesAllowed 表示访问对应方法时所应该具有的角色**(常用)**
示例:
@RolesAllowed({“USER”, “ADMIN”})
该方法只要具有"USER"或 "ADMIN"任意一种权限就可以访问。这里可以省略前缀ROLE_,实际的权 限可能是ROLE_ADMIN 。
@RolesAllowed( “ADMIN”)
该方法只有具有 "ADMIN"权限才可以访问。
(2)@PermitAll表示允许所有的角色进行访问,也就是说不进行权限控制
(3)@DenyAll是和PermitAll相反的,表示无论什么角色都不能访问

2.3.2 @Secured注解

@Secured 注解标注的方法进行权限控制的支持,其值默认为disabled。(常用)
示例:
@Secured(“ROLE_ADMIN”)
该方法只有具有 "ADMIN"权限才可以访问。

2.3.3 支持表达式的注解

@PreAuthorize 在方法调用之前,基于表达式的计算结果来限制对方法的访问 (常用)
示例:
@PreAuthorize("#userId == authentication.principal.userId or hasAuthority(‘ADMIN’)")
void changePassword(@P(“userId”) long userId ){ 。。。 }
这里表示在changePassword方法执行之前,判断方法参数userId的值是否等于principal中保存的当前用户的 userId,或者当前用户是否具有ROLE_ADMIN权限,两种符合其一,就可以访问该方法。

@PreAuthorize(“hasRole(‘ROLE_ADMIN’)”)
该方法只有具有 "ADMIN"权限才可以访问。

@PreAuthorize(“authentication.principal.username == ‘zzz’”)
//只有zzz用户可以执行该方法

@PostAuthorize 允许方法调用,但是如果表达式计算结果为false,将抛出一个安全性异常
示例:
@PostAuthorize User getUser(“returnObject.userId == authentication.principal.userId or hasPermission(returnObject, ‘ADMIN’)”);

@PostFilter 允许方法调用,但必须按照表达式来过滤方法的结果
@PreFilter 允许方法调用,但必须在进入方法之前过滤输入值

2.4 使用spring security标签实现页面端的权限控制(显示控制)

在jsp页面中我们可以使用spring security提供的权限标签来进行权限控制。
首先在pom.xml文件中导入taglibs依赖:
在这里插入图片描述
在侧边栏 页面aside.jsp中导入taglib标签:
在这里插入图片描述
常用的两种标签如下:

2.4.1 authorize 标签

authorize标签通过判断用户是否具有对应的权限而控制其进入系统时所看见的内容显示。

如下:具有ADMIN权限才能看见订单管理这一项。
在这里插入图片描述

2.4.2 authentication标签

获取当前登录的用户名,用于页面显示。
在这里插入图片描述

property: 只允许指定Authentication所拥有的属性,可以进行属性的级联获取,如“principle.username”, 不允许直接通过方法进行调用。
在这里插入图片描述

3. Tips

配置文件中指定的access表示登录进入系统点击任何功能模块,进行任何操作均需要具有ADMIN或USER权限。在这里插入图片描述
服务器端用spring security框架的注解实现方法级别的控制,页面用标签实现显示控制。

另外,配置文件中,注意以下各个跳转页面的含义。
在这里插入图片描述

  • 用户名密码正确但是不具有任何角色的用户也可以登录成功进入到系统的index.jsp页面,但是由于权限不足无法打开系统的其他任何界面。
  • 用户名密码错误会显示failer.jsp页面
  • 只要用户名密码正确就可以登录成功打开index.jsp或main.jsp界面(这里我的这两个页面是一样的,即系统主页,从index.jsp中会直接跳转到main.jsp)。

参考:
https://blog.csdn.net/zlt995768025/article/details/80141913
https://www.cnblogs.com/lenve/p/11242055.html
黑马教程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值