authentication.getPrincipal()为什么总是返回username而不是UserDetails的实现类

authentication.getPrincipal()为什么总是返回username而不是UserDetails的实现类

关于这个问题在网上找了很多,有说需要实现UserDetailsService,也有说要改源码,感觉都不靠谱,决定自己解决问题。

getPrincipal是Authentication接口下的一个方法,而getPrincipal方法有以下几个实现
在这里插入图片描述
经过断点调试,发现走的UsernamePasswordAuthenticationToken类中的实现方法,但是这个方法实现只是简单返回了principal这个属性,看不出什么东西
在这里插入图片描述
既然是对象的属性,那么再找找这个类的构造方法,发现UsernamePasswordAuthenticationToken的构造方法有两个
在这里插入图片描述
继续排查这两个构造方法的引用情况,发现其中一个构造方法被我们使用到
在这里插入图片描述
问题到这里已经很明显了,大概率是我们自定义的权限验证出了问题,查看SecurityAuthenticationProvider的authenticate方法

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 自定义的验证逻辑
        final String username = String.valueOf(authentication.getPrincipal());
        final String password = String.valueOf(authentication.getCredentials());
        Set<GrantedAuthority> authorities = new HashSet<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        UserEntity userEntity = new UserEntity();
        userEntity.setUsername(username);
        userEntity.setPassword(password);
        userEntity.setAuthorities(authorities);
        // 返回UsernamePasswordAuthenticationToken对象
        return new UsernamePasswordAuthenticationToken(username, password, authorities);
    }

关注返回的对象

return new UsernamePasswordAuthenticationToken(username, password, authorities);

所用的构造器传入的第一个参数是username,看上面的构造方法代码不难发现这就是principal属性的值,所以,只需要改为

return new UsernamePasswordAuthenticationToken(userEntity, password, authorities);

至此,问题解决。

总结

关注SecurityAuthenticationProvider的authenticate方法的返回值,你返回什么,authentication.getPrincipal()就得到什么,很合理!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值