tctc4869
V2EX  ›  Java

Java 有现成的权限系统框架么?

  •  1
     
  •   tctc4869 · Jun 18, 2020 · 10292 views
    This topic created in 2340 days ago, the information mentioned may be changed or developed.

    之前自己开发 web 项目的时候,关于权限系统的编码,自己从 0 开始编写了一个简易的权限系统,基于 RBAC 的那种,不过还是想看看有没有现成的权限系统设计。

    现在的我不太喜欢注解配置,注解侵入太强,想找一套式非侵入式的权限系统框架,权限校验在类似 Web 拦截器之类的地方进行权限校验。各位知道有哪些现成的么,或者有什么思路么

    至于是哪个 WebMVC 框架,这里不说明,因为 WebMVC 框架可能使用的是 Spring MVC,也可能是 Vert.x web,也可能是 JFinal,也可能是 Servlet 。所以侵入程度不要太强。尽可能与 WebMVC 的代码解耦。这是一个重点。

    权限校验代码不能写在 Controller 类里,所以 shiro 之类通过注解的方式实现权限校验的方式被排除了,如果有 Controller 需要特定的权限校验,那这个交给拦截器之类的组件来进行。

    Supplement 1  ·  Jun 19, 2020
    没用过 abac 权限模型,abac 相对 RBAC 简单么?我记得有网站说 abac 比 rbac 权限模型,虽然灵活,但配置相对复杂。是这样的么?关于 abac 权限,有哪些好的资料说明呢
    54 replies  •  2020-10-17 22:23:01 +08:00
    byaiu
    byaiu
    Jun 18, 2020
    1
    shiro 可以吗
    beginor
    beginor
    Jun 18, 2020 via Android❤️1
    2
    最近也在看 spring 全家桶, 但是似乎没有像 asp.net core identity 同等级别的认证框架,Java 不太熟, 无意引战, 有的话望各路大神告知
    tctc4869
    tctc4869
    OP
    Jun 18, 2020
    3
    @byaiu 这个不行
    Sharuru
    Sharuru
    Jun 18, 2020
    4
    轻量的比较少,以前用过几个,但是实现不咋地,要 customize 一下很烦。
    现在框架流行注解是为了易用,一句话就能解决的东西就不用再像以前 XML 里写茫茫多的代码了;也符合 Spring Boot 的风格。

    话说回来,其实几个叫得出名字的验证框架其最终还是利用 Filter 来满足功能的。

    比如 Spring Security 就是其中之一,把预制好的,各种各样来源、功能的 Filter 注册到 Web 访问的生命周期中来实现自己的验证链。

    翻阅一下 AuthenticationChain 的代码,或者官方文档的 Security Filter Chain 章节,楼主就应该能有思路自己撸一套喜欢的验证框架了。
    zifangsky
    zifangsky
    Jun 18, 2020
    5
    试试我写的这个权限控制框架?名字叫:easylimit ( https://github.com/zifangsky/easylimit )

    如果不喜欢注解形式,可以类似下面这样配置:
    https://i.loli.net/2020/06/18/TRnWw1o8NJ6Vjl4.jpg
    chihiro2014
    chihiro2014
    Jun 18, 2020
    6
    Spring Security 不香么
    sadfQED2
    sadfQED2
    Jun 18, 2020 via Android
    7
    权限系统跟业务耦合太严重了,还是自己写比较好,以后改也好改
    tctc4869
    tctc4869
    OP
    Jun 18, 2020 via Android
    8
    @Sharuru
    我不喜欢注解配置权限的原因是,注解是硬编码。
    tsdbg
    tsdbg
    Jun 19, 2020
    9
    Vert.x 如何?直接在 Router 里校验
    xuanbg
    xuanbg
    Jun 19, 2020
    10
    xuanbg
    xuanbg
    Jun 19, 2020
    11
    @sadfQED2 只要有资源管理和资源对应的接口配置,就可以达成完全无耦合的目标。底层原理就是用可配置的约定替代依赖而已,比较形象点的说法就是对暗号,只认暗号不认人。
    lihongming
    lihongming
    Jun 19, 2020 via iPhone
    12
    自从用了 AWS Serverless 框架,就再也不写权限系统了,只需规划好路径,Cognito 和 APIGateway 会自动拦截无权访问的。

    这种按路径控制权限的思想通用型很好,我觉得应该有现成的框架(可惜我不知道)
    yukiloh
    yukiloh
    Jun 19, 2020
    13
    @lihongming 是不是通过 lambda 来调用.前段时间想研究的,我是 idea19.1,aws toolkit 版本高了报错,低了还是报错,最后火大了一键卸载
    wangxiaoaer
    wangxiaoaer
    Jun 19, 2020 via Android
    14
    @lihongming 跟由层实现的只能是基本的能不能访问的情况,但如果同一个接口需要根据角色返回不同数据,实现不了吧。
    waa
    waa
    Jun 19, 2020 via Android
    15
    @wangxiaoaer 这种怎么实现
    inwar
    inwar
    Jun 19, 2020 via Android
    16
    @wangxiaoaer 路由大粒度,服务小粒度
    lihongming
    lihongming
    Jun 19, 2020 via iPhone
    17
    @wangxiaoaer 根据角色返回不同数据就不算“权限”控制的范畴了吧?

    这种需求似乎没什么可用的框架,都得自己根据用户的 group id 或者 role id 自己写规则
    Hanggi
    Hanggi
    Jun 19, 2020
    18
    @wangxiaoaer 你这样不就把角色和其他数据耦合在一起了吗?
    jzphx
    jzphx
    Jun 19, 2020
    19
    注解侵入强,属硬编码不能认同。既然都 RBAC 了,菜单角色权限都在 db 或者缓存,可配置性很强。不在 controller 控制权限不科学啊,难道控制的不是菜单权限而是数据权限?放在 service 层对业务侵入肯定强啊
    wangyanrui
    wangyanrui
    Jun 19, 2020
    20
    1. 权限基本高度耦合业务
    2. 越轻量越需要自己定制,越重量约可以多组合起来,少定制
    2. SpringSecurity 基本满足楼主要求,虚拟出来一个 FIlter 链去做权限校验,只需要导 starter,切换成数据库,配配配即可
    tctc4869
    tctc4869
    OP
    Jun 19, 2020
    21
    @jzphx 菜单角色权限都在 db 的话,我可以直接通过后台管理界面配置权限,通过 web 拦截器校验权限,这样没注解什么事情了。另外我开头说明中,指定了没有指明是用哪个 WebMVC 框架,要在这个情况下考虑比较通用的权限校验问题。至于特殊的权限校验,那是另外的事情。

    注解本来就是硬编码,一旦运行就不可更改(如果需要要改注解对象内容,那还要注解干什么?相比注解,还有更好的配置方式,是建造者模式与链式调用)。
    hantsy
    hantsy
    Jun 19, 2020❤️1
    22
    @beginor Spring Security 以前的 Oauth 子项目有一个 Authentication Server 实现, 现在这个项目处于维护状态。

    https://spring.io/projects/spring-security-oauth

    现在这新的 Spring Security 5 核心包括了 OAuth2 模块,完全重写了。目前核心还没包括 Authenticaiton Server,从安全的角度看,这个不属于安全控制的一些部分,Spring Security 的 OAuth Client 和 Resource Server 的实现可以与任何兼容 OAuth2 和 OIDC 协议的 Authentitcation Server 交互。

    不过,Spring 启动一个新的社区项目。
    https://github.com/spring-projects-experimental/spring-authorization-server

    其实现在做安全,只要选择一个 OAuth 兼容的认证服务就行了,如果应用程序不大(像淘宝,天猫),没必要自己建 auth server,可以选择第三方 IDP 服务,如 auth0,okta 都不错。自建的话,现成的开源产品很多,基于 .DotNet Core Identity Server, Redhat 的 Keycloak (基本很多自建的首选),Spring 母公司的之前 Uaa(现在在 CloudFoundry 下面), https://github.com/cloudfoundry/uaa 。
    wangxiaoaer
    wangxiaoaer
    Jun 19, 2020
    23
    @lihongming #17 严格讲算的,最典型的部门、人员这种带层级的架构,那么一般数据可见范围是要控制在本部门的。
    tctc4869
    tctc4869
    OP
    Jun 19, 2020
    24
    @tsdbg 这不是 WebMVC 框架的问题,与 Vert.x 或 Sring MVC 等无关,要抛开 WebMVC 框架,单独来看待 Web 权限校验。
    wangxiaoaer
    wangxiaoaer
    Jun 19, 2020
    25
    @Hanggi #18

    我能想到的一种方案:所有跟权限相关的查询属性都作为查询参数,然后还是路由层进行控制。

    比如针对这样一个需求:经理角色再查询用户的时候只能看到本部门的用户,并且只能看到姓名这个字段

    1 用户接口的粒度要足够细:查询部门、查询字段要作为参数显式声明(客户端提供)

    2 用户接口严格按照查询参数做查询,这一步不做验证工作。

    2 路由层根据查询参数做过滤实现授权和权限验证,这个过滤就可以借助一些配置文件实现相对的通用。
    qq1340691923
    qq1340691923
    Jun 19, 2020❤️1
    26
    这也不愿意,那也不愿意,你是来引战的吧
    tctc4869
    tctc4869
    OP
    Jun 19, 2020
    27
    @qq1340691923 自说自话,先射箭,后画靶子
    tctc4869
    tctc4869
    OP
    Jun 19, 2020
    28
    @wangxiaoaer 权限配置,除了考虑 OA 系统的组织体系,还有客户体系。

    比如有些权限无法手动配置,由业务逻辑配置,比如客户申请某类资源的使用,后台审核能否客户使用,审核通过就会赋予客户用户对某类资源的角色权限,这个时候权限就会侵入到业务里,对于这类你有什么好的解耦思路。
    wangxiaoaer
    wangxiaoaer
    Jun 19, 2020
    30
    @tctc4869 #28 这跟我之前说的思路不冲突,审核通过后赋予了某个客户某个新的权限,那么把这个权限信息写入到路由验证所依赖的那个配置文件中就可以了啊。

    “ 路由层根据查询参数做过滤实现授权和权限验证,这个过滤就可以借助一些配置文件实现相对的通用。”

    这个地方刚没有细说,单实际上整个权限验证的核心就是这一块,他将权限规则抽象成表达式的方法存到某个配置中,又能够解析表达式在路由层结合请求参数做过滤。这个配置可以是文件也可以是数据库,所以既放置预先配置好的规则,当然也可以在运行时更新。
    zengyuxi
    zengyuxi
    Jun 19, 2020
    31
    什么叫抛开 webMVC 框架?你确定不是过来逗我们玩的?你了解“Spring Security”吗?提问题之前,先问是不是,再问为什么!
    tctc4869
    tctc4869
    OP
    Jun 19, 2020
    32
    @wangxiaoaer 关于这个思路,有链接提供完整的说明么?
    wucao219101
    wucao219101
    Jun 19, 2020
    33
    Spring Security +1
    wangxiaoaer
    wangxiaoaer
    Jun 19, 2020
    34
    @tctc4869 #32 没有啊。 我只是瞎捷豹想的啊,但是感觉应该有可行性。
    tctc4869
    tctc4869
    OP
    Jun 19, 2020
    35
    @wangxiaoaer 我有个想法,我的开头有说明是脱离 WebMVC 框架,来思考权限校验,我想搞一个 HttpContext 的 java 抽象类,然后我的权限校验就基于该抽象类体系进行。如果要较好的处理权限校验的话,这个抽象类应该添加哪些设计了?
    hantsy
    hantsy
    Jun 19, 2020
    36
    @tctc4869 你说这些纯粹是你的业务需求(权限设置),和业务绑定自己要实现,用什么安全架构,框架,技术有什么关系?
    ixx
    ixx
    Jun 19, 2020
    37
    试试 keycloak?
    Alex5467
    Alex5467
    Jun 19, 2020
    38
    @byaiu 他都说 shiro 之类通过注解的方式实现权限校验的方式被排除了
    safilar
    safilar
    Jun 19, 2020
    39
    @tctc4869 你这种需求很简单,shiro 那种到处要写注解在代码里面确实有一些问题,比如开发自己忘记写了,变成只有前端走个校验了。
    BQsummer
    BQsummer
    Jun 19, 2020
    40
    我顺便问个题外话,rbac 肯定满足不了中等公司的需求,abac 有啥落地方案吗,我们现在公司是自研的权限系统,基于树的,很绕,介于 rbac 和 abac 之间,很多功能修修补补
    safilar
    safilar
    Jun 19, 2020
    41
    @tctc4869 其实就是重写一个拦截器,将接口上的注解直接映射到 redis,这里需要自己建存储。然后统一由拦截器读取配置,这里用 spring Security 举例子重写 AccessDecisionManager decide 的方法。第一个参数 Authentication 是你自定义的权限集合(一般读表);第二个参数,一般取 request 用的,
    safilar
    safilar
    Jun 19, 2020
    42
    第三个参数 urlConfigAttribute 用户传递过来的 uri,你通过这个方法直接鉴权;如果是权限路由表是 pathvariable 这种,你就可以使用 AntPathRequestMatcher spring 自带的识别器来做权限识别是否匹配。
    safilar
    safilar
    Jun 19, 2020
    43
    无论是 rbac 还是 abac 这种方式实现都是比较简单,至少注解不用写了。
    wangxiaoaer
    wangxiaoaer
    Jun 19, 2020 via Android
    44
    @BQsummer abac 结合 spring expression 我觉得有搞头。
    tctc4869
    tctc4869
    OP
    Jun 19, 2020
    45
    @safilar
    没用过 abac 权限模型,abac 相对 RBAC 简单么?我记得这个有网站说 abac 比 rbac 权限模型,要复杂。是这样的么?
    xuanbg
    xuanbg
    Jun 19, 2020
    46
    @tctc4869 你这个需求其实是多租户体系的典型应用。对于多租户体系来说,每个租户都有独立的角色权限管理。譬如淘宝店铺后台就是个多租户应用,钉钉也是。我们都是阿里的用户,在我们注册店铺后,店铺就是阿里的租户,我们既是阿里的普通用户,也是店铺这个租户的管理用户。

    这些概念对于没深入有研究过权限管理系统的人来说可能稍复杂,但可以简单看一下 https://github.com/xuanbg/auth 这个项目里面的表结构。
    xuanbg
    xuanbg
    Jun 19, 2020
    47
    tctc4869
    tctc4869
    OP
    Jun 20, 2020
    48
    @xuanbg 根据你所说的,ABAC 权限体系的用途上,我感觉,就是基于平台应用级别的权限系统,不同的组织,在这个平台上,可以有不一样的权限体系。至少每个组织对内权限体系,可以不一样。而 RBAC 权限模型做不到这一点,至少如果有两个客户群体有不一样的权限需求,RBAC 实现起来就会很困难。是这样的么?
    xuanbg
    xuanbg
    Jun 20, 2020
    49
    @tctc4869
    权限其实就是资源的分配,而资源的集合就是应用。最原始的 RBAC,只是不考虑多租户,而且是单应用的权限数据模型。

    而在多租户多应用体系里面,你所谓的客户群体,本质上都是用户而已。你把他们看做两个群体,实际上不过是他们是两个应用的用户罢了。

    我项目里面的 role 表中,tenant_id 表示角色的租户归属,app_id 表示角色的应用归属。也就是同样应用的管理员,A 租户和 B 租户是两个角色,他们各管各的且互相不可见。

    具体的关系,你看我这篇博客就明白了。https://www.cnblogs.com/xuanbg/p/12511509.html
    fox0001
    fox0001
    Jun 20, 2020 via Android
    50
    权限应该分为功能权限和数据权限。

    功能权限的话,filter ( Web 拦截器)应该是比较适合了。

    数据权限的话,很大程度依赖根据业务逻辑而设计的数据结构。
    Shikyou
    Shikyou
    Jun 24, 2020
    51
    @hantsy 也可以试一下国内的 Authing 。
    authing.cn 和 cognito / auth0 / okta 差不多,可以快速实现用户的 ABAC 和 RBAC
    hantsy
    hantsy
    Jun 24, 2020
    52
    @Shikyou AUTHING.CN 这种方向不错,不过国内推广应该没有国外那么容易。以前在项目推荐过 Stormpath (后来被 Okta 收购了)。国内的对于推荐一些方案如果他们自己没有弄过的,基本上我之前一些帖子见到那些言论一样,“用这个出了问题来谁背锅”,“你不能证明这个我们用的更好,为什么要换掉现成的东西”,“迁移到其它平台风险你能评估出来吗,这个工作量算谁的”。国内公司家长式的管理模式,培养都是一些巨婴一样的员工,不管什么方案,对于他们只要不要他们重新学习,不要他们动手就是最好的方案,每天用用 Copy,Paste 就完成工作就好了。

    接触国外到项目,自己没太多要求的基本都是走一下 JWT Token 完成了,有社交账号支持要求的,多种形式认证( 2fa, otp 等)的基本最终上线选择 okta 或 outh0 这些成熟方案比较多,有些使用的 API 或者方案是自己都是集成身份认证了,比如 Firebase 。开发过程中可能就是直接用一个 Basic Http 认证,对于大部分功能写测试比较简单。
    Shikyou
    Shikyou
    Jun 24, 2020
    53
    @hantsy 草。分析得太对了。感谢对 Authing 的认可,我们在小范围推广 ing
    hsluoyz
    hsluoyz
    PRO
    Oct 17, 2020
    54
    推荐下 jCasbin: https://github.com/casbin/jcasbin 支持 ACL 、RBAC 、ABAC 等访问控制模型
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1158 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 81ms · UTC 17:50 · PVG 01:50 · LAX 09:50 · JFK 12:50
    ♥ Do have faith in what you're doing.