Shiro登录认证流程

shiro认证流程

DeBug启动项目之后自己打一些断点

1 填写form表单之后 点击登录,shiro会帮我们做认证,验证用户的信息是否正确,正确就登录,不正确就重定向到登录页面
2:shiro第一步会进入到MyFormAuthenticationFilter.java 类中的onAccessDenied(ServletRequestrequest,ServletResponse response)方法中
2.1判断是否为登录请求,判断是否为登录提交,如果是,获取HttpServletRequest,根据HttpServletRequest来获取请求参数验证码code和登录类型(如果有单点登录)先判断登录类型,再判断验证码是否正确,具体的看代码

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (isLoginRequest(request, response)) {//判断是否为登录请求
            if (isLoginSubmission(request, response)) {//是否为登录提交请求
                HttpServletRequest httpServletRequest = (HttpServletRequest) request;
                String vercode = httpServletRequest.getParameter("code");//获取验证码
                String logtype = httpServletRequest.getParameter("logtype");//获取登录类型(有单点登录的时候)
                if (logtype.equals("0")) {//判断登录类型 0为普通登录
                	if (StringUtil.hasValue(vercode) && !vercode.toLowerCase().equals	(httpServletRequest.getSession()
                	         .getAttribute("_code"))) {//判断验证码信息
                        ResponseResults responseResults = ResponseResults.warn("验证码错误!");
                        output(response, responseResults);
                        return false;//中止filter链
                    }
                    return executeLogin(request, response);
                }
                else {
                	return executeLogin(request, response);//单点登录直接进行登录
                }
                
            } else {
                return true;
            }
        } else {
            saveRequestAndRedirectToLogin(request, response);
            return false;
        }
    }

3:F7跳出方法,进入自定义Realm(继承了AuthorizingRealm)中的doGetAuthenticationInfo(Authe nticationToken token)方法中,方法的返回值 AuthenticationInfo token中封装了从登录页面传回来的用户名和密码,判断登录类型,普通登录和单点登录的返回方式一样,返回的参数略有不同,

 @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    	ServletRequest request = ((WebSubject)SecurityUtils.getSubject()).getServletRequest(); 
        ServletResponse resp =((WebSubject)SecurityUtils.getSubject()).getServletResponse();
    	HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    	HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
    	String logtype = request.getParameter("logtype");
     
    	if (logtype.equals("1")) {//单点登录
    		String password = new String((char[])token.getCredentials());//获取密码
    		ResponseResults msg=sysSingleLoginService.identification_cooks((String) token.getPrincipal(), password,httpServletRequest,httpServletResponse);//调用单点登录验证方法
    		if (Integer.valueOf(msg.get("code").toString())==0) {
    			String userid=msg.get("msg").toString();//获取用户
    			
    			HttpSession session = httpServletRequest.getSession();
    			 session.setAttribute("SINGLEUSER",userid);//将用户封装到session中
    			 
    			return new SimpleAuthenticationInfo(userid, "", "");
    		}
    		else {
    			String err=msg.get("msg").toString();
    			switch(err){
    				case "-1":
    					throw new DisabledAccountException();
    		
    				case "-2":
    					throw new  UnknownAccountException();
    		
    				case "-3":
    					throw new  IncorrectCredentialsException();
    		
    				default: throw new AuthenticationException("");
    			}
    			 
    		}
    	}
    	//普通登录
        User user = userService.getuUserById((String) token.getPrincipal());
        if (null == user) {
            throw new UnknownAccountException();
        }
        if ("0".equals(user.getFlag())) {
            throw new DisabledAccountException();
        }
        return new SimpleAuthenticationInfo(user.getUserId(), user.getUserPassword(), getName());
    }


之后进入到RetryLimitHashedCredentialsMatchers类中的doCredentialsMatchers(AuthenticationToke
n token, AuthenticationInfo info)方法中判断密码是否正确,

@Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
    	ServletRequest request = ((WebSubject)SecurityUtils.getSubject()).getServletRequest();   
    	String logtype = request.getParameter("logtype");
 
    	String username = (String) token.getPrincipal();
        // retry count + 1
        AtomicInteger retryCount = passwordRetryCache.get(username);
        if (retryCount == null) {
            retryCount = new AtomicInteger(0);
            passwordRetryCache.put(username, retryCount);
        }
        if (retryCount.incrementAndGet() > 200) {
            // if retry count > 5 throw
            throw new ExcessiveAttemptsException();
        }

        logger.info("key=" + (String) info.getPrincipals().getPrimaryPrincipal());
        logger.info("user=" + new String((char[]) token.getCredentials()));
        logger.info("db=" + info.getCredentials());
        logger.info("des=" + ThreeDes.toEncode((String) info.getPrincipals().getPrimaryPrincipal(), new String((char[]) token.getCredentials())));
        
        if (logtype.equals("1")) {//单点登录
        	 String singleuser = request.getParameter("singleuser");
        	 return true;
        }
       
        
        
        boolean matches = ThreeDes.toEncode((String) info.getPrincipals().getPrimaryPrincipal(), new String((char[]) token.getCredentials())).equals(
                info.getCredentials());
        if (matches) {//密码匹配
            // clear retry count
            passwordRetryCache.remove(username);//清空缓存
        }
        return matches;
    }

匹配成功之后最后进入MyFormAuthenticationFilter 类中的onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,ServletResponse response)方法中
将用户的信息封装到session中,保存用户信息,记录登录日志,

protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,ServletResponse response) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpSession session = httpServletRequest.getSession();
        SysUser sysUser;
        String logtype = request.getParameter("logtype");
        if (logtype.equals("1")) {
        	String singleuser = session.getAttribute("SINGLEUSER").toString();
        	sysUser=sysUserService.getSysUserById(singleuser);
        }
        else {
        	sysUser = sysUserService.getSysUserById((String) token.getPrincipal());
        }
        //session.setMaxInactiveInterval(30 * 60);
        session.setAttribute("USERKEY", sysUser.getUserKey());
        session.setAttribute("USERID", sysUser.getUserId());
        UsernamePasswordToken tokenEx= (UsernamePasswordToken) token;
        String pass=String.valueOf(tokenEx.getPassword());
        session.setAttribute("USERDEFAULTVALUE", pass.equals("123456")); 
        session.setAttribute("USERIPARDESS", getIpAddress(httpServletRequest)); 
        
        
        
        sysUser.setLastIp(request.getRemoteAddr());
        sysUser.setLastTime(DateUtil.getDateTime());
        sysUserService.save(sysUser);

        sysLogingLogService.saveLoginLog(sysUser.getUserKey(), sysUser.getUserId(), sysUser.getUserName(), sysUser.getRegionCode(), sysUser.getFacultyCode(), getIpAddress(httpServletRequest));
        output(response, ResponseResults.ok());
        return false;
    }

重在流程走向

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值