SpringSecurity授权

简介

上一篇博客讲述了SpringSecurity的用户认证,用户认证的目的是让系统知道是谁在访问系统。而这篇博客主要讲述SpringSecurity的另一个功能鉴权,也就是权限控制,目的是你能在系统做什么。

SpringSecurity 授权

内置权限表达式

SpringSecurity使用Spring EL来支持,主要用于web访问和方法安全上,可以通过表达式判断是否具有访问权限,下面是SpringSecurity常用的内置表达式
在这里插入图片描述
在这里插入图片描述

URL安全表达式

1、设置url访问权限

// 设置/user/** 访问需要ADMIN角色
http.authorizeRequests().antMatchers("/user/**").hasRole("ADMIN");
// 设置/user/** 访问需要PRODUCT角色和IP地址为127.0.0.1
.hasAnyRole("PRODUCT,ADMIN")
http.authorizeRequests().antMatchers("/product/**")
.access("hasAnyRole('ADMIN,PRODUCT') and
hasIpAddress('127.0.0.1')");
// 设置自定义权限不足信息.
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);

2、自定义权限不足类

/**
* 自定义权限不足信息
*/
@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest,
HttpServletResponse resp, AccessDeniedException e) throws IOException,
ServletException {
resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("权限不足,请联系管理员!");
}
}

3、设置用户权限信息

// 先声明一个权限集合, 因为构造方法里面不能传入null
Collection<GrantedAuthority> authorities = new ArrayList<>();
if ("admin".equalsIgnoreCase(user.getUsername())) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
} else {
authorities.add(new SimpleGrantedAuthority("ROLE_PRODUCT"));
}

在web安全表达式引用自定义Bean授权

1、自定义授权bean

/**
* 自定义授权类
*/
@Component
public class MyAuthorizationService {
/**
* 检查用户是否有对应的访问权限
*
* @param authentication 登录用户
* @param request 请求对象
* @return
*/
public boolean check(Authentication authentication, HttpServletRequest
request) {
User user = (User) authentication.getPrincipal();
// 获取用户所有权限
Collection<GrantedAuthority> authorities = user.getAuthorities();
// 获取用户名
String username = user.getUsername();
// 如果用户名为admin,则不需要认证
if (username.equalsIgnoreCase("admin")) {
return true;
} else {
// 循环用户的权限, 判断是否有ROLE_ADMIN权限, 有返回true
for (GrantedAuthority authority : authorities) {
String role = authority.getAuthority();
if ("ROLE_ADMIN".equals(role)) {
return true;
}
}
}
return false;
}
}

2、配置类

//使用自定义Bean授权
http.authorizeRequests().antMatchers("/user/**").
access("@myAuthorizationService.check(authentication,request)");

3、携带变量配置

/**
* 检查用户是否有对应的访问权限
*
* @param authentication 登录用户
* @param request 请求对象
* @param id 参数ID
* @return
*/
public boolean check(Authentication authentication, HttpServletRequest
request, Integer id) {
if (id > 10) {
return false;
}
return true;
}

4、配置

//使用自定义Bean授权,并携带路径参数
http.authorizeRequests().antMatchers("/user/delete/{id}").
access("@myAuthorizationService.check(authentication,request,#id)");

Method安全表达式

针对方法级别的安全控制,SpringSecurity提供了四种注解方式,分别是@PreAuthorize、@PostAuthorize、@PreFilter 、@PostFilter

1、开启方法级别的注解配置

/**
* Security配置类
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启注解支持
public class SecurityConfiguration extends WebSecurityConfigurerAdapte

2、在方法上使用

@PreAuthorize
在进入方法前进行权限校验

@RequestMapping("/findAll")
@PreAuthorize("hasRole('ADMIN')")//需要ADMIN权限
public String findAll(Model model) 

@PostAuthorize
在方法执行后进行权限校验,适合校验有返回值的方法,根据返回信息进行校验

/**
* 根据ID查询用户
*
* @return
*/
@GetMapping("/{id}")
@ResponseBody
@PostAuthorize("returnObject.username==
authentication.principal.username")//判断查询用户信息是否是当前登录用户信息.否则没有
权限
public User getById(@PathVariable Integer id)

其中returnObject代表return 返回值

@PreFilter
对集合类型的参数进行过滤,将不符合条件的参数剔除

/**
* 商品删除-多选删除
*
* @return
*/
@GetMapping("/delByIds")
@PreFilter(filterTarget = "ids", value = "filterObject%2==0")//剔除参数为
基数的值
public String delByIds(@RequestParam(value = "id") List<Integer> ids)

@PostFilter
对集合类型的返回值进行过滤,剔除不符合要求的元素

/**
* 查询所有用户-返回json数据
*
* @return
*/
@RequestMapping("/findAllTOJson")
@ResponseBody
@PostFilter("filterObject.id%2==0")//剔除返回值ID为偶数的值
public List<User> findAllTOJson()

基于数据库的RBAC数据模型的权限控制

RABC简介

RABC权限模型既基于角色的权限控制
用户:系统接口访问的操作者
权限:能够访问接口或进行某些操作的资格
角色:具有一类相同操作权限的总称

关联关系

在这里插入图片描述

表结构

在这里插入图片描述

实施

1、动态查询数据库中用户的权限

public interface PermissionMapper extends BaseMapper<Permission> {
/**
* 根据用户ID查询权限
* *
* @param id
* @return
*/
@Select("SELECT p.* FROM t_permission p,t_role_permission rp,t_role
r,t_user_role ur,t_user u " +
"WHERE p.id = rp.PID AND rp.RID = r.id AND r.id = ur.RID AND
ur.UID = u.id AND u.id =#{id}")
List<Permission> findByUserId(Integer id);
}

2、给登录用户授权

// 先声明一个权限集合, 因为构造方法里面不能传入null
Collection<GrantedAuthority> authorities = new ArrayList<>();
// 查询用户对应所有权限
List<Permission> permissions = permissionService.findByUserId(user.getId());
for (Permission permission : permissions) {
// 授权
authorities.add(new
SimpleGrantedAuthority(permission.getPermissionTag()));
}

3、设置访问权限

// 查询数据库所有权限列表
List<Permission> permissions = permissionService.list();
for (Permission permission : permissions) {
//添加请求权限
http.authorizeRequests().
antMatchers(permission.getPermissionUrl()).hasAuthority(permission.getPermi
ssionTag());
}

页面标签的权限控制

在jsp页面或者是thymeleaf模板页面,我们可以使用SpringSecurity提供的权限标签来进行权限控制,首先要引入thymeleaf-extras-springsecurity依赖

标签介绍
判断用户是否已经登陆认证,引号内的参数必须是isAuthenticated()。
sec:authorize=“isAuthenticated()”
获得当前用户的用户名,引号内的参数必须是name。
sec:authentication=“name”
判断当前用户是否拥有指定的权限。引号内的参数为权限的名称。
sec:authorize=“hasRole(‘role’)”
1、在pom文件中引入依赖

<!--添加thymeleaf为SpringSecurity提供的标签 依赖 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>

2、在html中声明使用

<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

3、标签使用

<div class="leftnav">
<div class="leftnav-title">
<div sec:authorize="isAuthenticated()">
<span sec:authentication="name"></span>
<img src="images/y.jpg" class="radius-circle rotate-hover"
height="50" alt=""/></div>
</div>
<div sec:authorize="hasAuthority('user:findAll')">
<h2><span class="icon-user"></span>系统管理</h2>
<ul style="display:block">
<li><a href="/user/findAll" target="right"><span class="icon-caretright"></span>用户管理</a></li>
<li><a href="javascript:void(0)" onclick="toCors()" target="right">
<span
class="icon-caret-right"></span>跨域测试</a></li>
</ul>
</div>
<div sec:authorize="hasAuthority('product:findAll')">
<h2><span class="icon-pencil-square-o"></span>数据管理</h2>
<ul>
<li><a href="/product/findAll" target="right"><span class="iconcaret-right"></span>商品管理</a></li>
</ul>
</div>
</div>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值