我想将一个方法中权限验证与业务尽可能地解耦
例如下面这样一个方法
deleteDocument(String docId) { ... }
通过 docId 查找数据库中的 document 表,确认其中的 owner 是否是当前登录用户。 如果:1.是当前登录用户 2.不是当前登录用户,但当前登录用户是管理员 即判断有删除文档的权限,之后就进行纯粹的业务逻辑的代码。
请问上述操作 spring security 有实现的办法吗。或者说有其他的方法可以实现?谢谢大家!
1
liuxu 2021-06-02 09:51:54 +08:00
phper 用 laravel 就不会提出这种问题
|
2
Cbdy 2021-06-02 09:52:33 +08:00 via Android
Spring Security 是人间之屑,建议别用
你这种需求一个拦截器就完事儿了,比如这种 https://github.com/cbdyzj/natrium/blob/master/common/src/main/java/nano/support/validation/ValidateInterceptor.java |
3
Hugg 2021-06-02 09:55:04 +08:00 via Android
securityContextHolder 可以获取当前用户信息,做下 if else 即可
|
4
Huiao 2021-06-02 10:02:09 +08:00
换个思路,是否可以加个 mybatis 插件在删除语句后面拼接 sql 判断 owner 是否是当前用户
|
5
Hugg 2021-06-02 10:03:47 +08:00 via Android
或者你在 controller 加上 Authentication 参数
|
6
guxingke 2021-06-02 10:05:46 +08:00 1
PostAuthorize 注解 + SPEL 可解
===== @PostAuthorize("returnObject.owner == authentication.id") Doc findOwnerDoc(String docId); |
7
xuanbg 2021-06-02 10:05:48 +08:00 2
spring security 把很多人带沟里去了。。。明明可以很简单的鉴权,上了 spring security 后就变得很复杂。
|
8
jorneyr 2021-06-02 10:10:33 +08:00 2
通过 docId 查找数据库中的 document 表:
这个已经属于业务逻辑级别了,得查询数据库,不是框架级能够处理的。甚至不同业务表的数据 owner 字段名都不一样,有的用 user_id, 有的用 owner_id,有的用 creator_id 都可能,是千变万化的,不同的请求查询的表也不同,框架提供的权限判断只是 permission 和 role 级别的,数据级的没看到过。 |
9
jorneyr 2021-06-02 10:15:49 +08:00
当然自定义注解,实现查询指定的表和字段以及匹配的值和相关权限,在执行方法前先通过注解进行处理,判断是否有足够的权限也是可以做到,但这不是 spring security 自带的功能。
|
10
CingFuture OP 谢谢各位的回答,我好好消化一下!
|
11
fpure 2021-06-02 11:50:49 +08:00
我反正只把 spring security 当过滤器用,完全不用它的权限之类的,这样还是挺好用的
|
12
lybcyd 2021-06-02 15:02:26 +08:00 1
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#el-pre-post-annotations
文档就可以解答你的疑惑,启用注解鉴权后,直接利用注解搞定 |
13
xianzhe 2021-06-02 16:11:42 +08:00 1
```
@DeleteMapping("/{id}") @PreAuthorize("#Id == null || @documentService.hasDeletePermission(#Id)") public ResponseEntity<?> getGlobalAlertList(@RequestParam String Id){ } ``` |
14
xianzhe 2021-06-02 16:12:24 +08:00
大概这样子写,很方便
|
15
SuperXRay 2021-06-02 16:30:51 +08:00
我也有个问题
spring security 如何无密码授权? |
16
lostSoul 2021-06-02 19:19:13 +08:00
@SuperXRay 我当初也遇到这个问题 授权微信小程序登录 但是微信小程序并没有密码这个玩意 我最后是自己重写了 provider 类 不走 passwordEncoder 这个东西就行了
|
17
lostSoul 2021-06-02 19:22:49 +08:00 1
@SuperXRay springSecurity 自带的 DaoAuthenticationProvider 会 调用注入的 passwordEncoder 你只要自己写个类 覆盖下 DaoAuthenticationProvider 的 authenticate 方法调用了 additionalAuthenticationChecks 这个方法 你可以复写掉 authenticate 这个方法 直接调用 service 就行了 我当初为了这个 把 security 的源码和文档看了三天调试了三天
|
18
lostSoul 2021-06-02 19:24:51 +08:00
网上一直吐槽 security 太重了 但是其实真正去看了 security 的源码你会学到很多骚操作新思想 不过不可否认他确实过度设计了
|
19
mikulch 2021-06-02 22:45:23 +08:00
@guxingke
@lostSoul 不知道两位是否遇到过使用 SpEL + PreAuthrorize 自定义权限校验逻辑的时候,框架抛出的 AccessdeniedException 异常,无法被 ExceptionTranslater 异常处理拦截器处理的情况没有? 看 debug 的过程,就是当权限投票失败处理以后,正常抛出了 AccessdeniedException,但是这个没有向上一直抛到 ExceptionTranslater,而是莫名其妙直接到了 DispatchServlet 然后被处理打印到控制台,然后程序返回到 ExceptionTranslater 以后直接就没有异常了的情况? |
20
tamer 2021-06-02 22:54:01 +08:00
但凡看过一遍官方文档,也不会说出过度设计,故意复杂化这种话.
|
21
JamesMackerel 2021-06-03 09:48:31 +08:00 via iPhone
看到有人在这里劝退我就放心了。
|
23
litchinn 2021-06-04 09:24:35 +08:00
方法级别的权限,我赞同 13 楼,我也是这么用的
|