请教大家一个关于 spring security 鉴权的问题

2021-06-02 09:46:47 +08:00
 CingFuture

我想将一个方法中权限验证与业务尽可能地解耦

例如下面这样一个方法

deleteDocument(String docId) { ... }

通过 docId 查找数据库中的 document 表,确认其中的 owner 是否是当前登录用户。 如果:1.是当前登录用户 2.不是当前登录用户,但当前登录用户是管理员 即判断有删除文档的权限,之后就进行纯粹的业务逻辑的代码。

请问上述操作 spring security 有实现的办法吗。或者说有其他的方法可以实现?谢谢大家!

3338 次点击
所在节点    Java
23 条回复
liuxu
2021-06-02 09:51:54 +08:00
phper 用 laravel 就不会提出这种问题
Cbdy
2021-06-02 09:52:33 +08:00
Spring Security 是人间之屑,建议别用

你这种需求一个拦截器就完事儿了,比如这种

https://github.com/cbdyzj/natrium/blob/master/common/src/main/java/nano/support/validation/ValidateInterceptor.java
Hugg
2021-06-02 09:55:04 +08:00
securityContextHolder 可以获取当前用户信息,做下 if else 即可
Huiao
2021-06-02 10:02:09 +08:00
换个思路,是否可以加个 mybatis 插件在删除语句后面拼接 sql 判断 owner 是否是当前用户
Hugg
2021-06-02 10:03:47 +08:00
或者你在 controller 加上 Authentication 参数
guxingke
2021-06-02 10:05:46 +08:00
PostAuthorize 注解 + SPEL 可解

=====
@PostAuthorize("returnObject.owner == authentication.id")
Doc findOwnerDoc(String docId);
xuanbg
2021-06-02 10:05:48 +08:00
spring security 把很多人带沟里去了。。。明明可以很简单的鉴权,上了 spring security 后就变得很复杂。
jorneyr
2021-06-02 10:10:33 +08:00
通过 docId 查找数据库中的 document 表:
这个已经属于业务逻辑级别了,得查询数据库,不是框架级能够处理的。甚至不同业务表的数据 owner 字段名都不一样,有的用 user_id, 有的用 owner_id,有的用 creator_id 都可能,是千变万化的,不同的请求查询的表也不同,框架提供的权限判断只是 permission 和 role 级别的,数据级的没看到过。
jorneyr
2021-06-02 10:15:49 +08:00
当然自定义注解,实现查询指定的表和字段以及匹配的值和相关权限,在执行方法前先通过注解进行处理,判断是否有足够的权限也是可以做到,但这不是 spring security 自带的功能。
CingFuture
2021-06-02 10:25:41 +08:00
谢谢各位的回答,我好好消化一下!
fpure
2021-06-02 11:50:49 +08:00
我反正只把 spring security 当过滤器用,完全不用它的权限之类的,这样还是挺好用的
lybcyd
2021-06-02 15:02:26 +08:00
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#el-pre-post-annotations

文档就可以解答你的疑惑,启用注解鉴权后,直接利用注解搞定
xianzhe
2021-06-02 16:11:42 +08:00
```
@DeleteMapping("/{id}")
@PreAuthorize("#Id == null || @documentService.hasDeletePermission(#Id)")
public ResponseEntity<?> getGlobalAlertList(@RequestParam String Id){
}
```
xianzhe
2021-06-02 16:12:24 +08:00
大概这样子写,很方便
SuperXRay
2021-06-02 16:30:51 +08:00
我也有个问题
spring security 如何无密码授权?
lostSoul
2021-06-02 19:19:13 +08:00
@SuperXRay 我当初也遇到这个问题 授权微信小程序登录 但是微信小程序并没有密码这个玩意 我最后是自己重写了 provider 类 不走 passwordEncoder 这个东西就行了
lostSoul
2021-06-02 19:22:49 +08:00
@SuperXRay springSecurity 自带的 DaoAuthenticationProvider 会 调用注入的 passwordEncoder 你只要自己写个类 覆盖下 DaoAuthenticationProvider 的 authenticate 方法调用了 additionalAuthenticationChecks 这个方法 你可以复写掉 authenticate 这个方法 直接调用 service 就行了 我当初为了这个 把 security 的源码和文档看了三天调试了三天
lostSoul
2021-06-02 19:24:51 +08:00
网上一直吐槽 security 太重了 但是其实真正去看了 security 的源码你会学到很多骚操作新思想 不过不可否认他确实过度设计了
mikulch
2021-06-02 22:45:23 +08:00
@guxingke
@lostSoul

不知道两位是否遇到过使用 SpEL + PreAuthrorize 自定义权限校验逻辑的时候,框架抛出的 AccessdeniedException 异常,无法被 ExceptionTranslater 异常处理拦截器处理的情况没有?

看 debug 的过程,就是当权限投票失败处理以后,正常抛出了 AccessdeniedException,但是这个没有向上一直抛到 ExceptionTranslater,而是莫名其妙直接到了 DispatchServlet 然后被处理打印到控制台,然后程序返回到 ExceptionTranslater 以后直接就没有异常了的情况?
tamer
2021-06-02 22:54:01 +08:00
但凡看过一遍官方文档,也不会说出过度设计,故意复杂化这种话.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/780775

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX