Springboot中使用ShiroRealm进行登录用户的密码校验

1、登录时调用login

	/**
     * 登录
     */
    @GetMapping(API_PREFIX + PATH + "/login")
    public ResponseEntity loginGo(HttpServletRequest request,String userName, String password) {
        Subject currentUser = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(userName)) {
            queryWrapper.eq("USER_NAME", userName);
        }
        HttpSession session = request.getSession(true);
        User user = userService.getOne(queryWrapper);
        Map map = new HashMap();
        if (user != null) {
            try {
                currentUser.login(token);
                if (currentUser.isAuthenticated() == true) {
                    map.put("code", "1");
                    map.put("message", "登录成功");
                    map.put("userId", user.getId());
                    session.setAttribute("user", user);
                    return ResponseEntity.ok(map);
                } else {
                    map.put("code", "0");
                    map.put("message", "用户名密码错误");
                    return ResponseEntity.ok(map);
                }
            } catch (AuthenticationException e) {
                e.printStackTrace();
                System.out.println("登录失败");
            }
        }
        map.put("code", "0");
        map.put("message", "用户不存在");
        return ResponseEntity.ok(map);

2、配置ShiroConfig,后面token中的密码加密用

    /**
     * 密码匹配凭证管理器
     *
     * @return
     */
    @Bean(name = "hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 采用MD5方式加密
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        // 设置加密次数
        hashedCredentialsMatcher.setHashIterations(1024);
        return hashedCredentialsMatcher;
    }

3、通过上面的currentUser.login(token)方法会自动调用ShiroRealm的doGetAuthenticationInfo方法

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        // 将token装换成UsernamePasswordToken
        UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
        // 获取用户名即可
        String username = upToken.getUsername();
        // 查询数据库,是否查询到用户名和密码的用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(username)) {
            queryWrapper.eq("USER_NAME", username);
        }
        User userInfo = userService.getOne(queryWrapper);

        if(userInfo != null) {
            // 如果查询到了,封装查询结果,返回给我们的调用
            Object principal =  userInfo;
            Object credentials = userInfo.getPassword();
            // 获取盐值,即用户名(用此值和token中的密码进行加密,加密结果和credentials比较,如果一致就算登录成功)
            ByteSource salt = ByteSource.Util.bytes(username);
            String realmName = this.getName();
            // 将账户名,密码,盐值,realmName实例化到SimpleAuthenticationInfo中交给Shiro来管理
            info = new SimpleAuthenticationInfo(principal, credentials, salt, realmName);
        }else {
            // 如果没有查询到,抛出一个异常
            throw new AuthenticationException();
        }
        return info;
    }

4、会调用抽象父类的AuthenticatingRealm的方法getAuthenticationInfo

    public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info = this.getCachedAuthenticationInfo(token);
        if (info == null) {
            info = this.doGetAuthenticationInfo(token);
            log.debug("Looked up AuthenticationInfo [{}] from doGetAuthenticationInfo", info);
            if (token != null && info != null) {
                this.cacheAuthenticationInfoIfPossible(token, info);
            }
        } else {
            log.debug("Using cached authentication info [{}] to perform credentials matching.", info);
        }

        if (info != null) {
            // 通过info中保存的realmName获取加密方法、加密次数、加密salt、加密token中的密码
            // 加密完的token密码和info中保存的密码进行比较,如果相等,返回true,验证通过
            this.assertCredentialsMatch(token, info);
        } else {
            log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}].  Returning null.", token);
        }
        return info;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值