| 在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/"; |
| |
| |
| @PreAuthorize("hasAuthority('sys:user')") |
| @GetMapping(value = {"/", ""}) |
| public String user() { |
| return HTML_PREFIX + "user-list"; |
| } |
| |
| |
| @PreAuthorize("hasAnyAuthority('sys:user:add', 'sys:user:edit')") |
| @GetMapping(value={"/form"}) |
| public String form() { |
| return HTML_PREFIX + "user-form"; |
| } |
| |
| |
| @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(); |
| } |
| |
| |
| |
| @PreFilter(filterTarget = "ids", value = "filterObject > 0") |
| @RequestMapping("/batch/{ids}") |
| @ResponseBody |
| public MengxueguResult deleteByIds(@PathVariable List<Long> ids) { |
| return MengxueguResult.ok(ids); |
| } |
| |
| |
| @PostFilter("filterObject != authentication.principal.username") |
| @RequestMapping("/list") |
| @ResponseBody |
| public List<String> page() { |
| List<String> userList = Lists.newArrayList("meng", "xue", "gu"); |
| return userList; |
| } |
| |
| } |
| |
| <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> |
| |
| |
| <div class="info"> |
| <a sec:authentication="principal.username" href="#" class="d-block">梦老师</a> |
| </div> |
| |
| |
| <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> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术