记springSecurity报错:AnonymousAuthenticationToken cannot be cast to UsernamePasswordAuthenticationToken

在使用 springSecurity 登录用户 + 自定义注解+aop实现日志记录问题时,再给业务方法 登录功能添加日志注解时,报错:

java.lang.ClassCastException: org.springframework.security.authentication.AnonymousAuthenticationToken cannot be cast to org.springframework.security.authentication.UsernamePasswordAuthenticationToken

很明显的错误,AnonymousAuthenticationToken 类型不可用扮演 UsernamePasswordAuthenticationToken 类型,但是,我们给 SecurityContextHolder 里添加用户信息都是用的类型转换,怎么会出这个问题呐?

通过打断点,发现其中的问题。由于我是给登录功能添加的日志,所以定义的实现OncePerRequestFilter 接口的过滤器 JwtAuthenticationTokenFilter  中先去判断是否又token,因为还没有登录,所以没有存入SecurityContextHolder。然后,通过aop切面去实现日志整理的,在获取用户信息时是没有用户信息的,所以报错。

 

 所以,JwtAuthenticationTokenFilter 还没有存入用户信息的时候,就执行了切面整理日志,所以报错了。写代码还是得耐心啊!!

补充:JwtAuthenticationTokenFilter  是在切面之前执行的,只是登录功能是没有token的,所以也没有用户信息。

解决方案:登录时不走aop切面,登录成功日志入库。

    public ResponseResult login(User user) {
        long startTime = System.currentTimeMillis();
        //AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authentication =
                new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authentication);

        //如果认证没通过,给用户对应的提示
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("登录失败");
        }

        //如果认证通过了,使用userId生成一个jwt,jwt存入ResponseResult进行返回
        LoginUser loginUser = (LoginUser)authenticate.getPrincipal();
        String userId = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(userId);

        Map<String, String> map = new HashMap<>();
        map.put("jwt",jwt);
        //把完整的用户信息存入Redis,userId作为key
        redisCache.setCacheObject("login:"+userId,loginUser);
        // 添加日志
        // 填充日志内容
        long endTime = System.currentTimeMillis();
        SysLogOperation sysLogOperation = new SysLogOperation();
        sysLogOperation.setUserName(loginUser.getUser().getUserName());
        sysLogOperation.setCreateId(loginUser.getUser().getId());
        sysLogOperation.setStatus("0");
        Date date = new Date();
        sysLogOperation.setRequestTime(endTime -startTime);
        sysLogOperation.setCreateTime(date);
        sysLogOperation.setUpdateTime(date);
        sysLogOperation.setClassName("org.example.service.impl");
        sysLogOperation.setRequestMethod("login");
        sysLogOperationService.insertSysLog(sysLogOperation);
        return new ResponseResult(200,"登陆成功",map);
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值