security整合jwt自定义认证请求接口总是要认证

问题描述

用springSecurity+jwt做自定义登录描述的时候,发送任何请求携带了token还是会走默认的认证逻辑。并且也在自定义的jwt过滤器中做了认证逻辑。

解决方案

先看一下代码

// 生成authentication对象
SysUser sysUser = new SysUser();
sysUser.setAccount(claims.get("account").asString());
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(sysUser,sysUser.getAuthorities());
// 告诉security已经认证了,否则会再去认证
authenticationToken.setAuthenticated(true);
// 放入上下文
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
// 放行
doFilter(request, response, filterChain);

从jwt中读出载荷数据,生成UsernamePasswordAuthenticationToken 对象并且放入了上下文,但是还是会走认证逻辑。

跟着断点查看了很久发现在SpringSecurity的认证拦截器中有个方法调用的是Authentication接口的isAuthentication方法,如果返回的是true表示认证了,就不会走认证逻辑,否则重新认证。

于是尝试手动设置改成true

// 告诉security已经认证了,否则会再去认证
authenticationToken.setAuthenticated(true);

根本不行,不知道为啥,走不到这里。然后查看UsernamePasswordAuthenticationToken代码。终于发现构造方法用错了。

看一下这两种构造方法

 public UsernamePasswordAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
        this.credentials = credentials;
        super.setAuthenticated(true);
    }

三个参数,会设置认证标志

public UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
        super((Collection)null);
        this.principal = principal;
        this.credentials = credentials;
        this.setAuthenticated(false);
    }

两个参数,设置认证标识为未认证。

总结

也就是说我用错了构造方法,导致认证标识未改变,才会一直走认证逻辑。做后代码改成三参数的构造器就解决了

UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(sysUser, null,sysUser.getAuthorities());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值