shiro在jeesite中登录中的应用,我要在登录表单中传递参数,如何能在过滤器中传递验证

jeesite登录流程------》

一:

loginIndex.jsp 的登录表单提交------》FormAuthenticationFilter的createToken()方法,目的new UsernamePasswordToken()

protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
   String username = getUsername(request);
   String password = getPassword(request);
    String xx1 = request.getParameter("xx");
   if (password==null){
      password = "";
   }
   boolean rememberMe = isRememberMe(request);
   String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
   String captcha = getCaptcha(request);
   boolean mobile = isMobileLogin(request);
   //return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
   return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile,xx1);
}

二:

---------------》SystemAuthorizingRealm 的doGetAuthenticationInfo(),这里从上一步的UsernamePasswordToken类中取到表单的用户名,密码等,再从数据库取出用户名,密码进行比较验证

/**
 * 认证回调函数, 登录时调用
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
   UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
   String xx1 = token.getXx();
   int activeSessionSize = getSystemService().getSessionDao().getActiveSessions(false).size();
   if (logger.isDebugEnabled()){
      logger.debug("login submit, active session size: {}, username: {}", activeSessionSize, token.getUsername());
   }
   
   // 校验登录验证码
   if (LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
      Session session = UserUtils.getSession();
      String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
      if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
         throw new AuthenticationException("msg:验证码错误, 请重试.");
      }
   }
   
   // 校验用户名密码
   User user = getSystemService().getUserByLoginName(token.getUsername());
   if (user != null) {
      if (Global.NO.equals(user.getLoginFlag())){
         throw new AuthenticationException("msg:该已帐号禁止登录.");
      }
      byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
      return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()), 
            user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
   } else {
      return null;
   }
}

三:(二)中的验证如果失败,则执行FormAuthenticationFilter的onLoginFailure()方法

/**
 * 登录失败调用事件
 */
@Override
protected boolean onLoginFailure(AuthenticationToken token,
      AuthenticationException e, ServletRequest request, ServletResponse response) {
   String className = e.getClass().getName(), message = "";
   if (IncorrectCredentialsException.class.getName().equals(className)
         || UnknownAccountException.class.getName().equals(className)){
      message = "用户或密码错误, 请重试.";
   }
   else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
      message = StringUtils.replace(e.getMessage(), "msg:", "");
   }
   else{
      message = "系统出现点问题,请稍后再试!";
      e.printStackTrace(); // 输出到控制台
   }
       request.setAttribute(getFailureKeyAttribute(), className);
       request.setAttribute(getMessageParam(), message);
       return true;
}

接着执行:LoginController的loginFail()方法

    * 登录失败,真正登录的POST请求由Filter完成
    */
   @RequestMapping(value = "${adminPath}/login", method = RequestMethod.POST)
   public String loginFail(HttpServletRequest request, HttpServletResponse response, Model model) {

/*
      CookieUtils.setCookie(response, "LOGINED", "false");
*/

      Principal principal = UserUtils.getPrincipal();
        String xx = request.getParameter("xx");
      // 如果已经登录,则跳转到管理首页
      if(principal != null){
         return "redirect:" + adminPath;
      }

      String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
      boolean rememberMe = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM);
      boolean mobile = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_MOBILE_PARAM);
      String exception = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
      String message = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM);
      //登录失败,设置logined false
      CookieUtils.setCookie(response, "LOGINED", "false");
      if (StringUtils.isBlank(message) || StringUtils.equals(message, "null")){
         message = "用户或密码错误, 请重试.";
      }
      model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, username);
      model.addAttribute(FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM, rememberMe);
      model.addAttribute(FormAuthenticationFilter.DEFAULT_MOBILE_PARAM, mobile);
      model.addAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME, exception);
      model.addAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM, message);
      
      if (logger.isDebugEnabled()){
         logger.debug("login fail, active session size: {}, message: {}, exception: {}", 
               sessionDAO.getActiveSessions(false).size(), message, exception);
      }
      
      // 非授权异常,登录失败,验证码加1。
      if (!UnauthorizedException.class.getName().equals(exception)){
         model.addAttribute("isValidateCodeLogin", isValidateCodeLogin(username, true, false));
      }
      
      // 验证失败清空验证码
      request.getSession().setAttribute(ValidateCodeServlet.VALIDATE_CODE, IdGen.uuid());
      
      // 如果是手机登录,则返回JSON字符串
      if (mobile){
           return renderString(response, model);
      }
      
      //return "modules/sys/sysLogin";
      model.addAttribute("errormessage", message);
      return "modules/news/loginIndex";

   }

再接着执行:LoginController的login()方法

/**
    * 管理登录
    */
   @RequestMapping(value = "${adminPath}/login", method = RequestMethod.GET)
   public String login(HttpServletRequest request, HttpServletResponse response, Model model) {
      Principal principal = UserUtils.getPrincipal();
//    // 默认页签模式
//    String tabmode = CookieUtils.getCookie(request, "tabmode");
//    if (tabmode == null){
//       CookieUtils.setCookie(response, "tabmode", "1");
//    }
      
      if (logger.isDebugEnabled()){
         logger.debug("login, active session size: {}", sessionDAO.getActiveSessions(false).size());
      }
      
      // 如果已登录,再次访问主页,则退出原账号。
      if (Global.TRUE.equals(Global.getConfig("notAllowRefreshIndex"))){
         CookieUtils.setCookie(response, "LOGINED", "false");
      }
      
      // 如果已经登录,则跳转到管理首页
      if(principal != null && !principal.isMobileLogin()){
         return "redirect:" + adminPath;
      }
//    String view;
//    view = "/WEB-INF/views/modules/sys/sysLogin.jsp";
//    view = "classpath:";
//    view += "jar:file:/D:/GitHub/jeesite/src/main/webapp/WEB-INF/lib/jeesite.jar!";
//    view += "/"+getClass().getName().replaceAll("\\.", "/").replace(getClass().getSimpleName(), "")+"view/sysLogin";
//    view += ".jsp";
      //return "modules/sys/sysLogin";
      return "modules/news/loginIndex";
   }

四:(二)中的验证如果成功,执行FormAuthenticationFilterissueSuccessRedirect()方法,

@Override
   protected void issueSuccessRedirect(ServletRequest request,
         ServletResponse response) throws Exception {
//    Principal p = UserUtils.getPrincipal();
//    if (p != null && !p.isMobileLogin()){
          WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
//    }else{
//       super.issueSuccessRedirect(request, response);
//    }
   }

接着执行:LoginController的index()方法

/**
    * 登录成功,进入管理首页
    */
   @RequiresPermissions("user")
   @RequestMapping(value = "${adminPath}")
   public String index(HttpServletRequest request, HttpServletResponse response,Model model) {
        String xx = request.getParameter("xx");
      CookieUtils.setCookie(response, "LOGINED", "true");

      Principal principal = UserUtils.getPrincipal();

      // 登录成功后,验证码计算器清零
      isValidateCodeLogin(principal.getLoginName(), false, true);
      
      if (logger.isDebugEnabled()){
         logger.debug("show index, active session size: {}", sessionDAO.getActiveSessions(false).size());
      }
      
      // 如果已登录,再次访问主页,则退出原账号。
      if (Global.TRUE.equals(Global.getConfig("notAllowRefreshIndex"))){
         String logined = CookieUtils.getCookie(request, "LOGINED");
         if (StringUtils.isBlank(logined) || "false".equals(logined)){
            CookieUtils.setCookie(response, "LOGINED", "true");
         }else if (StringUtils.equals(logined, "true")){
            UserUtils.getSubject().logout();
            return "redirect:" + adminPath + "/login";
         }
      }
      
      // 如果是手机登录,则返回JSON字符串
      if (principal.isMobileLogin()){
         if (request.getParameter("login") != null){
            return renderString(response, principal);
         }
         if (request.getParameter("index") != null){
            return "modules/sys/sysIndex";
         }
         return "redirect:" + adminPath + "/login";
      }
      
//    // 登录成功后,获取上次登录的当前站点ID
//    UserUtils.putCache("siteId", StringUtils.toLong(CookieUtils.getCookie(request, "siteId")));

//    System.out.println("==========================a");
//    try {
//       byte[] bytes = com.thinkgem.jeesite.common.utils.FileUtils.readFileToByteArray(
//             com.thinkgem.jeesite.common.utils.FileUtils.getFile("c:\\sxt.dmp"));
//       UserUtils.getSession().setAttribute("kkk", bytes);
//       UserUtils.getSession().setAttribute("kkk2", bytes);
//    } catch (Exception e) {
//       e.printStackTrace();
//    }
////      for (int i=0; i<1000000; i++){
////         //UserUtils.getSession().setAttribute("a", "a");
////         request.getSession().setAttribute("aaa", "aa");
////      }
//    System.out.println("==========================b");
      /*return "modules/sys/sysIndex";*/
      return "redirect:" + "cc/zdh" + "/getZy";
   }


总得讲,首先request被formAuthenticationFilter接收到,然后传给createToken函数,该函数从request中取出name and  password,然后生成自定义的一个token传给了SystemAuthorizingRealm中的doGetAuthenticationInfo验证。其中SystemAuthorizingRealm内有systemService的实例,该实例含有userDAO能取出数据库中的name and password 接着由这俩密码生成SimpleAuthenticationInfo,再由info中的逻辑来验证。




一般要在表单添加验证参数,如<input name="xx" />  

1。先在UsernamePasswordToken 中添加参数

/**
 * 用户和密码(包含验证码)令牌类
 * @author ThinkGem
 * @version 2013-5-19
 */
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {

   private static final long serialVersionUID = 1L;

   private String captcha;
   private boolean mobileLogin;
   //自己加的参数
   private String xx;
   public UsernamePasswordToken(String username, char[] password,
                         boolean rememberMe, String host, String captcha, boolean mobileLogin,String xx) {
      super(username, password, rememberMe, host);
      this.captcha = captcha;
      this.mobileLogin = mobileLogin;
      this.xx=xx;
   }
 
 

2。FormAuthenticationFilter的createToken()方法中得到参数,传到UsernamePasswordToken中

protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
   String username = getUsername(request);
   String password = getPassword(request);
    String xx1 = request.getParameter("xx");
   if (password==null){
      password = "";
   }
   boolean rememberMe = isRememberMe(request);
   String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
   String captcha = getCaptcha(request);
   boolean mobile = isMobileLogin(request);
   //return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
   return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile,xx1);
}
 
 

3。SystemAuthorizingRealm 的doGetAuthenticationInfo(),这里从上一步的UsernamePasswordToken类中取到表单的参数xx,进行比较验证

/**
 * 认证回调函数, 登录时调用
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
   UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
   String xx1 = token.getXx();
   int activeSessionSize = getSystemService().getSessionDao().getActiveSessions(false).size();
   if (logger.isDebugEnabled()){
      logger.debug("login submit, active session size: {}, username: {}", activeSessionSize, token.getUsername());
   }
   
   // 校验登录验证码
   if (LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
      Session session = UserUtils.getSession();
      String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
      if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
         throw new AuthenticationException("msg:验证码错误, 请重试.");
      }
   }
   
   // 校验用户名密码
   User user = getSystemService().getUserByLoginName(token.getUsername());
   if (user != null) {
      if (Global.NO.equals(user.getLoginFlag())){
         throw new AuthenticationException("msg:该已帐号禁止登录.");
      }
      byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
      return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()), 
            user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
   } else {
      return null;
   }
}

一篇不错的博文:点击打开链接

猜你喜欢

转载自blog.csdn.net/qq_29347295/article/details/80678110
今日推荐