在Spring Security中实现方法级的安全性,最常见办法是使用特定的注解,将这些注解应用到需要保护的方法上
这些注解不仅可以直接加 controller 方法上, 也可以注解 Service 或 DAO 类中的方法
注解 |
描述 |
@PreAuthorize |
在方法调用前进行权限检查,表达式为 true 允许调用, 反之则无权限调用 |
@PostAuthorize |
在方法调用后进行权限检查,如果表达式计算结果为false,抛出异常403不允许访问;returnObject 代表方法的返回值, 可以使用 returnObject 对方法返回值进行验证 |
@PreFilter |
允许方法调用,但必须在进入方法之前过滤方法参数值 |
@PostFilter |
允许方法调用,但必须按照表达式来过滤方法的返回值;returnObject 代表方法的返回值, 可以使用 returnObject 对方法返回值进行验证 |
- 要使用注解控制权限,需要在security配置类中开启配置
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Controller
@RequestMapping("/user")
public class SysUserController {
private static final String HTML_PREFIX = "system/user/";
// 拥有sys:user权限,则可以访问该接口
@PreAuthorize("hasAuthority('sys:user')")
@GetMapping(value = {"/", ""})
public String user() {
return HTML_PREFIX + "user-list";
}
// 有 'sys:user:add' 或 'sys:user:edit'权限 的用户可以访问
@PreAuthorize("hasAnyAuthority('sys:user:add', 'sys:user:edit')")
@GetMapping(value={"/form"})
public String form() {
return HTML_PREFIX + "user-form";
}
// 返回值的code等于200,则调用成功有权限访问该接口,否则报错403
@PostAuthorize("returnObject.code == 200")
@RequestMapping("/{id}")
@ResponseBody
public MengxueguResult deleteById(@PathVariable Long id) {
if(id < 0) {
return MengxueguResult.build(500, "id不能小于0", id);
}
return MengxueguResult.ok();
}
// 过滤请求参数:filterTarget 指定哪个参数,filterObject是集合中的每个元素,
// 如果value表达式为true的数据则不会被过滤,否则就过滤掉
@PreFilter(filterTarget = "ids", value = "filterObject > 0")
@RequestMapping("/batch/{ids}")
@ResponseBody
public MengxueguResult deleteByIds(@PathVariable List<Long> ids) {
return MengxueguResult.ok(ids);
}
// 过滤返回值:filterObject是返回值集合中的每一个元素,当表达式为true则对应元素会返回
@PostFilter("filterObject != authentication.principal.username")
@RequestMapping("/list")
@ResponseBody
public List<String> page() {
List<String> userList = Lists.newArrayList("meng", "xue", "gu");
return userList;
}
}
# web模块添加依赖
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
# 添加命名空间
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
# 获取认证后的用户名
<div th:text="${#authentication.principal.username}">
</div>
# 拥有指定的权限时,显示按钮
<div th:if="${#authorization.expression('hasAuthority(''sys:user:add'')')}">
新增
</div>
# 方式2:获取认证后的用户名
<div class="info">
<a sec:authentication="principal.username" href="#" class="d-block">梦老师</a>
</div>
# 方式2:拥有指定的权限时,显示按钮
<button sec:authorize="hasAuthority('sys:role:add')" type="button" title="新增">
新增
</button>
<div sec:authorize-url = "/admin" >
只有通过身份验证的用户, 且具有调用 “/admin” URL权限时,才会显示此内容。
</div>
<div sec:authorize-url = "POST /admin" >
只有通过身份验证的用户, 且具有调用POST方式的 “/admin” URL权限时,才会显示此内容。
</div>