V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
CingFuture
V2EX  ›  Java

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

  •  
  •   CingFuture · 2021-06-02 09:46:47 +08:00 · 3311 次点击
    这是一个创建于 1276 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    例如下面这样一个方法

    deleteDocument(String docId) { ... }

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

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

    23 条回复    2021-06-04 09:24:35 +08:00
    liuxu
        1
    liuxu  
       2021-06-02 09:51:54 +08:00
    phper 用 laravel 就不会提出这种问题
    Cbdy
        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
    Hugg
        3
    Hugg  
       2021-06-02 09:55:04 +08:00 via Android
    securityContextHolder 可以获取当前用户信息,做下 if else 即可
    Huiao
        4
    Huiao  
       2021-06-02 10:02:09 +08:00
    换个思路,是否可以加个 mybatis 插件在删除语句后面拼接 sql 判断 owner 是否是当前用户
    Hugg
        5
    Hugg  
       2021-06-02 10:03:47 +08:00 via Android
    或者你在 controller 加上 Authentication 参数
    guxingke
        6
    guxingke  
       2021-06-02 10:05:46 +08:00   ❤️ 1
    PostAuthorize 注解 + SPEL 可解

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

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

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

    看 debug 的过程,就是当权限投票失败处理以后,正常抛出了 AccessdeniedException,但是这个没有向上一直抛到 ExceptionTranslater,而是莫名其妙直接到了 DispatchServlet 然后被处理打印到控制台,然后程序返回到 ExceptionTranslater 以后直接就没有异常了的情况?
    tamer
        20
    tamer  
       2021-06-02 22:54:01 +08:00
    但凡看过一遍官方文档,也不会说出过度设计,故意复杂化这种话.
    JamesMackerel
        21
    JamesMackerel  
       2021-06-03 09:48:31 +08:00 via iPhone
    看到有人在这里劝退我就放心了。
    SuperXRay
        22
    SuperXRay  
       2021-06-03 10:37:06 +08:00
    @lostSoul 感谢,这个问题确实困扰我挺久
    litchinn
        23
    litchinn  
       2021-06-04 09:24:35 +08:00
    方法级别的权限,我赞同 13 楼,我也是这么用的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1163 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:38 · PVG 02:38 · LAX 10:38 · JFK 13:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.