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

也谈 spring security 复杂度

  •  
  •   giiiiiithub · 12 天前 · 1966 次点击
    看到很多人说 spring security 复杂。个人认为复杂以下几个方面。(说句废话:研究过其实也就不复杂了)

    第一,spring security 的 filter 和如何配置 filter 这两部分的设计是分离的,恰恰是如何配置 filter 这部分做了高度抽象(涉及 HttpSecurity 、WebSecurity 、SecurityConfigurer 、SecurityBuilder 相关接口),导致不熟悉的用户很难将 filter 内部和配置串联起来。我认为这些高度抽象的配置相关设计让用户感到复杂的罪魁祸首。


    第二,通常最符合我们直觉的是:一个请求会经过哪些 filter ,以 url 的角度来描述 filter 序。但事实上配置起来可不是这么回事,配置时我们通常是:这个 filter 需要匹配哪些 url ,站在了 filter 的角度去匹配 url 。当有人接手我们的代码,或者我们自己,在稍微复杂一点的个性化需求下,也需做一个心理模型的转换,转换到一个请求应该先后经过哪些 filter 才能达到我们的预期。

    第三,spring security 的 filter 某些设计是有些复杂,比如用户密码登录 filter 又涉及到 authenticationManager ,用户信息查询、密码处理以及登录成功失败如何按需处理等等,鉴权部分又涉及到表达式,但其实 debug 串一串还好。

    第四,filter 是有序的,比如登录 filter 前后有一些重要的 filter ,可能和 session/cookie 相关,可能和 SecurityContext 相关,可能和异常相关,这一部分我觉得遵循"filter 有序"debug 串一串,读一读源码其实行也还好。如果想要知道 servlet 的 filter 是怎么搞的,spring 的 filter 又是如何桥接到 servlet 中的 filter 的,filter 又是怎么到 controller 的,怎么样可以 filter 直接 response 而不用到 controller ,怎么样可以让一个请求不走 filter 直达 controller 可能还需要再花点功夫。



    暂时想到这些。综合起来我觉得导致用户感到复杂的就是"高度抽象的配置接口",其他看看官方文档,滴一滴 bug ,看看源码接口设计其实都不是啥问题。
    19 条回复    2024-06-16 10:54:25 +08:00
    lululau
        1
    lululau  
       11 天前
    主要是文档写得太烂
    gowk
        2
    gowk  
       11 天前
    没错,隔壁帖子就是我说它复杂的 😄
    看 OP 对其略有研究,所以想问 OP
    有没有不是那么复杂的源码推荐阅读呢
    weijancc
        3
    weijancc  
       11 天前
    spring security 的 filter, 映像中想点进看实现, 结果绕了差不多 10 几层, 观感非常不好, 说实在这个 filter 就是 Java 项目的通病, 不停的架构.. 其实没有太大的研究价值, 我现在都是自己写个 spring mvc filter 进行登录授权就完事了.
    giiiiiithub
        4
    giiiiiithub  
    OP
       11 天前   ❤️ 1
    @gowk 没有,我是 debug 看源码看文档的经验。我的建议是先把三和四搞明白,也就是 filter 的设计和部分重要 filter 的实现部分先搞明白。再去研究下 filter 内部的各项依赖都是从哪些配置来的,最后再花时间去看配置相关的接口和实现逻辑。
    EastLord
        5
    EastLord  
       11 天前 via iPhone
    @weijancc 哥们说的是拦截器吗
    brookegas
        6
    brookegas  
       11 天前   ❤️ 1
    @weijancc
    同感!
    Spring 实属业界第一大毒瘤
    架构来架构去,架构出一座屎山
    逼着 Java 程序员挥汗如雨在屎山上耕耘,都整出斯德哥尔摩综合症了
    而且还有患者把这套恶物质向外传播,去污染 Javascript 和 Go ,搞出 js 版/Go 版的“IoC”的奇观
    fkdog
        7
    fkdog  
       11 天前
    spring security 从宏观架构上看当然简单,无非就是一连串的 filter 。
    复杂在于安全框架涉及的点太多了,可扩展点非常复杂非常多。
    单纯的 properties 或者 java config 无法直观的描述这些配置。
    于是 spring 自己搞了一堆 configurer api ,实现了 dsl 风格的 java 配置 api 。
    虽然配置的可读性提高了,但是要想看下代码,简直就跟天书一样。
    xuanbg
        8
    xuanbg  
       11 天前
    spring security 从根本上就不应该存在,生拉硬扯出来的怪物,能不复杂么。。。
    我自己在 Spring gateway 上实现用户身份验证和 url 鉴权,也就是那么几十行代码的事。而且涉及权限变更也不需要改代码,只需要改数据就行。

    为什么说 spring security 不应该存在,道理其实很简单。鉴权你得先授权啊,不同的授权方式就会需要匹配相应的鉴权方式。写死了鉴权方式,但又不给实现授权功能,这用起来不别扭才不正常。那为什么 spring security 不给实现一个授权功能呢?因为它做不知道你的资源和用户,做不了。用户还可以抽象,提供一个基类给你继承就完了。但资源是具体的,抽象不了。
    proudsky
        9
    proudsky  
       11 天前
    这玩意儿用过一次不会再用的东西,套娃多花里胡哨又重,不知道为什么很多开源的脚手架都在用。
    chuck1in
        10
    chuck1in  
       11 天前
    实现一个可以在生产环境用的身份认证和权限确实涉及到要写很多代码,而且都是各种配置代码

    https://github.com/ccmjga/mjga-scaffold/tree/main/src/main/java/com/mjga/config/security

    确实比较麻烦。

    不过 spring security 自带了很多东西,有些企业级开发用起来很方便。比如 Ldap 这个东西,其本身又有几种实现。很多传统行业都会去对接,但是从头接这个协议就非常麻烦,这一块儿 spring security 也通过策略设计模式自带了。

    另外那一大堆 filter 有很多都是和标准和安全相关的,你如果自己手写身份认证实际上是有很多安全漏洞的。一个健全的身份认证功能并不好写。

    互联网图快速变化,业务相对轻量,所以会觉得用 spring 很重。但是传统行业真的离不开这个东西,自带了很多套件太方便了。
    yusheng88
        11
    yusheng88  
       11 天前
    我大学时,刚接触 spring security ,当时学习主要靠视频、博客,感觉阅读英文有压力,下意识去逃避,结果就是折腾了 2 周才把动态 url 授权功能实现。

    最近升级到 springboot3 ,security6 ,直接看官方文档做集成 [还额外实现超管角色能访问人员 url 功能] ,2 个小时就搞定了,而且各种安全相关概念、集成方式都有详细说明,对比之下,国内的博客、技术视频质量非常差。

    说 spring security 复杂、文档差的,估计和我之前一样,学习使用就依赖于视频和国内博客吧
    spring security 的 api 版本兼容性差,这个倒是真的
    smilefox
        12
    smilefox  
       11 天前
    spring security 官方文档写的不错,我之前就是看官方文档学的
    Znemo
        13
    Znemo  
       11 天前
    可能是因为这个业务领域本身就花样很多,spring security 要兼顾大多数场景,就提升了复杂度,而往往开发者自己只关注某一种场景,但是要用 spring security 确要对大多数场景有一些基本的了解,所以也会觉得很麻烦。
    RicardoY
        14
    RicardoY  
       11 天前
    IoC 和 DI 本身没有什么问题吧(
    fantasy0v0
        15
    fantasy0v0  
       11 天前
    我是把 spring security 大部分的 filter 都移除了( sessionManagement 设置为 STATELESS )只保留部分,加了一些自己需要的(比如记录执行时间的 filter ),少了很多 filter 真爽,然后自己写了一个 HandlerInterceptor 来鉴权。
    这样就能保证鉴权过程中抛出的错误能被 RestControllerAdvice 处理到,不用在 spring security 里面单独处理异常。
    又能享受到 spring security 提供的 @PreAuthorize 等注解的便利(主要是注解这个)。🤭

    不过 api 接口变动确实让我改过好几次,目前是自己实现了一个 AuthenticationManager ,代替它原本的,不知道今后还会不会影响到我。
    a1oyss0925
        16
    a1oyss0925  
       11 天前
    研究过还是很复杂,一堆不知道干嘛的组件,一个认证就需要好几个类,不过解耦是真的解耦了。6.3 之前更看不懂那个 medadatasource ,还有 AccessDecisionVoter 什么的东西。不过 6.3 之后好像简化了
    iminto
        17
    iminto  
       11 天前 via Android   ❤️ 2
    我觉得喷 spring security 的人,大多是只花了几个小时学不懂也不会用而已,或者习惯了十多年前的快糙猛。

    这个东西哪有那么复杂,跟着教程一点一点来,慢慢扩展,再笨也就两三天功夫玩透了。

    自己撸一个简单的 filter ,确实可以做到几十行代码,半小时搞定,那又如何,还真当是十多年前的互联网红利期吗,一天几个需求,快糙猛,怎么方便怎么来,先上线再说,过几个月重构业务。

    我们有个老系统,需要支持传统的用户名密码登录,还要支持 ldap ,Kerberos ,Oauth 方式,就是用的 spring security 串起来,代码量不多,总就十几二十多个小类,但是分得很清晰。

    先抛弃自己成见,按照 spring security 的思路和套路来,多花点时间,也没那么难。
    litchinn
        18
    litchinn  
       10 天前
    spring security 很好,我觉得最难受的就是不同版本他的 api 不兼容,再加上文档就导致用的时候很乱很容易出错。就这个 api 兼容问题,感觉 spring security 不是 spring 团队里的一样,因为 spring 有着强大的向前兼容性。
    baolinliu442k
        19
    baolinliu442k  
       4 天前
    基础使用也就是自己定义一些 filter,配置类 addFilterAt addFilterAfter 之类的设置,再复杂的需求无非也就是加 filter. 熟悉 Spring Security 里的一些概念和基础类例如:Principle, AuthenticationManager,PasswordEncoder 还有他那个 getShareObjct, 还是有一些需要研究的地方才能用好吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2703 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:03 · PVG 23:03 · LAX 08:03 · JFK 11:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.