最近在学Spring Security,有些不懂的问题想请教各位大佬
开始当然是官方默认配置跑起来,还没有什么问题
后来自定义认证授权这里,我继承实现了UsernamePasswordAuthenticationFilter、AuthenticationProvider。
在UsernamePasswordAuthenticationFilter里网上都是setAuthenticationSuccessHandler来执行认证成功后的操作,是在里面直接写response就结束了,但我理解正常的场景应该是通过账号密码或者是token认证成功后继续向下执行该接口的具体业务。所以我没有指定setAuthenticationSuccessHandler,想让他继续执行下去,当他走到匿名过滤器AnonymousAuthenticationFilter的时候,第90行SecurityContextHolder.getContext().getAuthentication()为空,此时认证信息就没了然后生成一个匿名认证,在下一层FilterSecurityInterceptor就被403拦下来了
login 设的 permitAll
其余都是anyRequest().authenticated()
不知道该怎么操作才能调到具体接口执行下面,还望各位大佬指点一下
代码地址
https://github.com/ChiMuYuan/demo/tree/main/security
先谢谢老哥指点了。
我看了DaoAuthenticationProvider里面一些逻辑,最终调用的就是createSuccessAuthentication,返回的就是一个UsernamePasswordAuthenticationToken,我因为只是验证学习框架,没有写任何逻辑直接就返回了一个带GrantedAuthority集合的UsernamePasswordAuthenticationToken。
然后也进入了我自己写的success的handler,successHandler里面authentication入参的authenticated=true,但他还是继续往下走了,就到了 AnonymousAuthenticationFilter没了认证信息
我用了addFilterAt替换了原来的过滤器
我理解的是进入了我自己写的AuthenticationSuccessHandler就认为成功了,但是按老哥的说法只要后续进入了 AnonymousAuthenticationFilter,不管前面走没走successHandler就认为授权没通过。所以现在问题就是怎样才算真正授权通过了,我重写successHandler,直接用SavedRequestAwareAuthenticationSuccessHandler都试了
我这里是form改json
实在是没有搞懂,还请老哥指教,因为只是自己学的,里面代码很乱,后续我看整理下贴代码
这里面重写hanler也只是直接写getWriter返回了吧,能继续走下去访问到具体url的业务接口吗
我发现问题了,是因为SessionCreationPolicy.STATELESS,使用token这里就不创建session比较好,但这样认证就会变成不通过,只要不加STATELESS就可以了
最终问题:
SecurityContextPersistenceFilter在初始化的时候会使用默认的sessionContext,因为禁用了session,所以在AnonymousAuthenticationFilter之前执行的SecurityContextPersistenceFilter所初始化的repo(SecurityContextRepository)为NullSecurityContextRepository,从名字可知这是spring为防止null error 所构建的空repository,没有实际逻辑。所以在AnonymousAuthenticationFilter时,登录信息都被repo读取出来的null认证信息覆盖了,所以认证信息丢失,然后在AnonymousAuthenticationFilter里面被赋予了匿名权限。
所以解决方案有两种:
- 自己写一个SecurityContextPersistenceFilter(本人未验证,不知其中是否还有什么坑)
- 在AnonymousAuthenticationFilter的位置加入一个过滤器,使用SecurityContextHolder.getContext().setAuthentication(xxxxx)将认证成功或识别信息放入,这个过滤器里就可以写token的自定义逻辑(本方法已上传github,连接在1楼)
1 个赞