第一,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 ,看看源码接口设计其实都不是啥问题。