java干几年,回到解放前 2023-10-11 23:54 采纳率: 66.7%
浏览 31

springSecurity使用中登陆的AuthenticationService与预期不符

springSecurity使用中AuthenticationService与预期不符

@Service
public class AuthenticationServiceImpl implements AuthenticationService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache<UsersLogin> redisCache;


    @Override
    public ResponseWrapper<Object> login(RequestWrapper<UsersLogin> requestWrapper) {
        //AuthenticationManager authentication进行用户认证
        UsersLogin usersLogin=requestWrapper.getData();

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(usersLogin.getUsername(),usersLogin.getPassword());
        Authentication  authenticate = authenticationManager.authenticate(authenticationToken);

        if (Objects.isNull(authenticate)){
            throw new RuntimeException("用户名或密码错误");
        }
        //如果认证通过。使用userid生成jwt 。jwt存入ResponseWrapper返回
        UsersLogin user= (UsersLogin) authenticate.getPrincipal();
        String userId = user.getUserId().toString();
        String jwt = JwtTokenUtil.generateToken("login"+userId);
        //把完整的用户信息存入redis userId作为key
        redisCache.cacheObject("login"+userId,user,10, TimeUnit.MINUTES);
        //把token响应给前端
        return ResponseWrapper.success(null,jwt);
    }
}

如果密码错误,上面这段代码执行到Authentication authenticate = authenticationManager.authenticate(authenticationToken);时抛出异常:

org.springframework.security.authentication.BadCredentialsException: 用户名或密码错误

并没有像网上的教程那样把authenticate 赋值为null
这是我练习的参考案例


感觉网上security的教程都是这里判断是否为null,而Ai软件的提示是这样的:


在代码中,使用authenticationManager.authenticate(authenticationToken)方法进行用户认证后,如果认证失败,会抛出AuthenticationException异常,而不是返回null。因此,判断authenticate是否为null是不正确的。应该使用try-catch语句来捕获AuthenticationException异常,如果捕获到异常,则说明认证失败。正确代码应该是下面这样的

try {
    Authentication authenticate = authenticationManager.authenticate(authenticationToken);
    // 如果认证通过了 使用userid 生成一个jwt jwt 存入ResponseResult 返回
    LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
    String userId = loginUser.getUser().getId().toString();
    String jwt = JwtUtil.createJWT(userId);
    HashMap<String,String> map = new HashMap<>();
    map.put("token",jwt);
    // 把完整的用户信息存入redis userid 作为key
    redisCache.setCacheObject("login:"+userId,loginUser);
    return new ResponseResult(200,"登录成功",map);
} catch (AuthenticationException e) {
    throw new RuntimeException("登录失败");
}

现在不知道到底该怎么做了

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-12 13:20
    关注

    【以下回答由 GPT 生成】

    问题分析: 根据代码分析,出现"org.springframework.security.authentication.BadCredentialsException: 用户名或密码错误"异常的原因是在执行authenticationManager.authenticate(authenticationToken)时,抛出了BadCredentialsException异常,而不是返回null。可能是因为密码错误导致认证失败。根据代码逻辑,如果认证通过,会生成jwt并将用户信息存入redis,然后返回jwt给前端。

    解决方案: 1. 首先,确认用户的登录凭证(用户名和密码)是否正确。 - 检查数据库中的用户名和密码是否正确。 - 确保输入的密码与数据库中保存的密码使用相同的加密算法进行加密。

    1. 如果密码错误而不是返回null,需要处理认证失败的情况并提供相应的错误信息给前端。

    针对这个问题,可以按照以下步骤进行处理:

    @Service
    public class AuthenticationServiceImpl implements AuthenticationService {
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Autowired
        private RedisCache<UsersLogin> redisCache;
    
    
        @Override
        public ResponseWrapper<Object> login(RequestWrapper<UsersLogin> requestWrapper) {
            UsersLogin usersLogin = requestWrapper.getData();
    
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(usersLogin.getUsername(), usersLogin.getPassword());
    
            try {
                Authentication authenticate = authenticationManager.authenticate(authenticationToken);
    
                // 如果认证通过。使用userid生成jwt 。jwt存入ResponseWrapper返回
                UsersLogin user = (UsersLogin) authenticate.getPrincipal();
                String userId = user.getUserId().toString();
                String jwt = JwtTokenUtil.generateToken("login+"+userId);
    
                // 把完整的用户信息存入redis userId作为key
                redisCache.cacheObject("login+"+userId, user, 10, TimeUnit.MINUTES);
    
                // 把token响应给前端
                return ResponseWrapper.success(null, jwt);
            } catch (AuthenticationException e) {
                // 认证失败,抛出自定义异常信息
                throw new RuntimeException("用户名或密码错误");
            }
        }
    }
    

    以上代码中加入了try-catch块来捕获AuthenticationException异常,并抛出自定义的异常信息"用户名或密码错误"。这样即可在密码错误时返回给前端正确的错误信息。

    这样可以解决springSecurity使用中登陆的AuthenticationService与预期不符的问题。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 修改了问题 10月12日
  • 创建了问题 10月11日

悬赏问题

  • ¥15 软件供应链安全是跟可靠性有关还是跟安全性有关?
  • ¥15 电脑蓝屏logfilessrtsrttrail问题
  • ¥20 关于wordpress建站遇到的问题!(语言-php)(相关搜索:云服务器)
  • ¥15 【求职】怎么找到一个周围人素质都很高不会欺负他人,并且未来月薪能够达到一万以上(技术岗)的工作?希望可以收到写有具体,可靠,已经实践过了的路径的回答?
  • ¥15 Java+vue部署版本反编译
  • ¥100 对反编译和ai熟悉的开发者。
  • ¥15 带序列特征的多输出预测模型
  • ¥15 Python 如何安装 distutils模块
  • ¥15 关于#网络#的问题:网络是从楼上引一根网线下来,接了2台傻瓜交换机,也更换了ip还是不行
  • ¥15 资源泄露软件闪退怎么解决?