一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

shiro 自定義認(rèn)證filter

 Bladexu的文庫 2018-03-17

比如說我想 加一個驗證碼 認(rèn)證,原來的userNamePasswordToken 就不夠用了,我需要自定義一個新的token.

public class SecurityToken extends UsernamePasswordToken {
    /**
     * 驗證碼
     */
    private String captcha;

    /**
     * 系統(tǒng)生成的驗證碼(從session獲?。?
     */
    private String captchaSession;

    /**
     * 構(gòu)造函數(shù)
     */
    public SecurityToken() {
        super();
    }

    /**
     * 構(gòu)造函數(shù)
     * @param username 用戶名
     * @param password 用戶密碼
     * @param captcha 驗證碼
     */
    public SecurityToken(String username, String password, String captcha) {
        super(username, password);
        this.captcha = captcha;
    }

    /**
     * 構(gòu)造函數(shù)
     * @param username 用戶名
     * @param password 用戶密碼
     * @param captcha 驗證碼
     * @param host 主機
     */
    public SecurityToken(String username, String password, String captcha, String host) {
        super(username, password, host);
        this.captcha = captcha;
    }

    /**
     * 構(gòu)造函數(shù)
     * @param username 用戶名
     * @param password 用戶密碼
     * @param captcha 驗證碼
     * @param rememberMe 記住我
     */
    public SecurityToken(String username, String password, String captcha, boolean rememberMe) {
        super(username, password, rememberMe);
        this.captcha = captcha;
    }

    /**
     * 構(gòu)造函數(shù)
     * @param username 用戶名
     * @param password 用戶密碼
     * @param captcha 驗證碼
     * @param rememberMe 記住我
     * @param host 主機
     */
    public SecurityToken(String username, String password, String captcha, boolean rememberMe, String host) {
        super(username, password, rememberMe, host);
        this.captcha = captcha;
    }


    /**
     * 獲得驗證碼
     * @return 驗證碼
     */
    public String getCaptcha() {
        return captcha;
    }

    /**
     * 設(shè)置驗證碼
     * @param captcha 驗證碼
     */
    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }

    /**
     * 獲得系統(tǒng)生成的驗證碼
     * @return 系統(tǒng)生成的驗證碼
     */
    public String getCaptchaSession() {
        return captchaSession;
    }

    /**
     * 設(shè)置系統(tǒng)生成的驗證碼
     * @param captchaSession 系統(tǒng)生成的驗證碼
     */
    public void setCaptchaSession(String captchaSession) {
        this.captchaSession = captchaSession;
    }
}

在這基礎(chǔ)上,我想要定義認(rèn)證過濾器:

public class SecurityAuthcFilter extends FormAuthenticationFilter {
    private static Logger logger = LoggerFactory.getLogger(SecurityAuthcFilter.class);

   /**
    * 默認(rèn)的驗證碼輸入框標(biāo)識
    */
   public static final String DEFAULT_CAPTCHA_PARAM = "captcha";

    /**
    * 默認(rèn)登錄后的轉(zhuǎn)向邏輯(是否跳轉(zhuǎn)到登錄前的界面)
    */
   public static final boolean DEFAULT_REDIRECT_TO_SAVED_REQUEST = false;

   /**
    * 默認(rèn)的編碼方式
    */
   public static final String DEFAULT_CHARACTER_ENCODING = "UTF-8";

   /**
    * 驗證碼輸入框標(biāo)識
    */
   private String captchaParam = DEFAULT_CAPTCHA_PARAM;

   /**
    * 登錄后的轉(zhuǎn)向邏輯(是否跳轉(zhuǎn)到登錄前的界面)
    */
   private boolean redirectToSavedRequest = DEFAULT_REDIRECT_TO_SAVED_REQUEST;

   /**
    * 編碼方式
    */
   private String characterEncoding = DEFAULT_CHARACTER_ENCODING;

    /**
     * 驗證碼的屬性Key(用于從session中獲取系統(tǒng)生成的驗證碼)
     */
    public static final String CAPTCHA_SESSION = "SECURITY.LOGIN.CAPTCHA";

    /**
     * 登錄錯誤輸入框元素名稱
     */
    public static final String LOGIN_FAILED_ELEMENT = "SECURITY.LOGIN.FAILED.ELEMENT";

    /**
     * 登錄錯誤提示信息
     */
    public static final String LOGIN_FAILED_MESSAGE = "SECURITY.LOGIN.FAILED.MESSAGE";

   /**
    * 根據(jù)登錄信息創(chuàng)建登錄用戶的token
    * @param request ServletRequest對象
    * @param response ServletResponse對象
    * @return 登錄用戶的token
    */
   @Override
   protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
      try {
         request.setCharacterEncoding(characterEncoding);
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      }
      String username = getUsername(request);
      String password = getPassword(request);
      String captcha = getCaptcha(request);
        String captchaSession = getCaptchaSession(request);
      boolean rememberMe = isRememberMe(request);
      String host = getHost(request);

        SecurityToken token = new SecurityToken(username, password, captcha, rememberMe, host);
        token.setCaptchaSession(captchaSession);

      return token;
   }

   /**
    * 獲取驗證碼輸入框標(biāo)識
    * @return 驗證碼輸入框標(biāo)識
    */
   public String getCaptchaParam() {
      return captchaParam;
   }

   /**
    * 設(shè)置驗證碼輸入框標(biāo)識
    * @param captchaParam 驗證碼輸入框標(biāo)識
    */
   public void setCaptchaParam(String captchaParam) {
      this.captchaParam = captchaParam;
   }

   /**
    * 獲取驗證碼輸入框標(biāo)識
    * @param request ServletRequest對象
    * @return 驗證碼輸入框標(biāo)識
    */
   protected String getCaptcha(ServletRequest request) {
      return WebUtils.getCleanParam(request, getCaptchaParam());
   }

    /**
     * 獲取驗證碼輸入框標(biāo)識
     * @param request ServletRequest對象
     * @return 驗證碼輸入框標(biāo)識
     */
    protected String getCaptchaSession(ServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        return (String)session.getAttribute(CAPTCHA_SESSION);
    }

   /**
    * 判斷是否跳轉(zhuǎn)到登錄前的界面
    * @return 是否跳轉(zhuǎn)到登錄前的界面
    */
   public boolean isRedirectToSavedRequest() {
      return redirectToSavedRequest;
   }

   /**
    * 設(shè)置是否跳轉(zhuǎn)到登錄前的界面
    * @param redirectToSavedRequest 是否跳轉(zhuǎn)到登錄前的界面
    */
   public void setRedirectToSavedRequest(boolean redirectToSavedRequest) {
      this.redirectToSavedRequest = redirectToSavedRequest;
   }

   /**
    * 獲取編碼方式
    * @return 編碼方式
    */
   public String getCharacterEncoding() {
      return characterEncoding;
   }

   /**
    * 設(shè)置編碼方式
    * @param characterEncoding 編碼方式
    */
   public void setCharacterEncoding(String characterEncoding) {
      this.characterEncoding = characterEncoding;
   }

   /**
    * 登錄失敗后的處理
    * @param request ServletRequest對象
    * @param ae 用戶認(rèn)證錯誤異常信息
    */
   @Override
   protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
        String element = getUsernameParam();
        if(ae instanceof AccountNotFoundException ||
                ae instanceof AccountStatusException ||
                ae instanceof AccountUnknownException) {
            element = getUsernameParam();
        }
        if(ae instanceof IncorrectPasswordException) {
            element = getPasswordParam();
        }
        if(ae instanceof IncorrectCaptchaException) {
            element = getCaptchaParam();
        }
        if(ae instanceof InactivePasswordException) {
           element = getPasswordParam();
        }
      request.setAttribute(LOGIN_FAILED_ELEMENT, element);
      request.setAttribute(LOGIN_FAILED_MESSAGE, ae.getMessage());
   }

   /**
    * 登錄成功后的處理
    * @param token 登錄用戶的token
    * @param subject 登錄用戶的Shiro信息
    * @param request ServletRequest對象
    * @param response ServletResponse對象
    * @return 是否登錄成功
    * @throws Exception 異常信息
    */
   @Override
   protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        //登錄成功后,從session中去除校驗碼
        Session session = subject.getSession();
        session.removeAttribute(CAPTCHA_SESSION);

        //觸發(fā)執(zhí)行鑒權(quán)方法
        SecurityManager.isSessionUserAdminRole();
      if (redirectToSavedRequest) {
         return super.onLoginSuccess(token, subject, request, response);
      } else {
         WebUtils.issueRedirect(request, response, getSuccessUrl());
         return false;
      }
   }
}


配置文件配置:

<bean id="securityAuthcFilter" class="com.credithc.scs.security.SecurityAuthcFilter">
    <!--<property name="failureKeyAttribute" value=""/>-->
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/doLogin"/>
    <property name="successUrl" value="/home"/>
    <property name="unauthorizedUrl" value="/login"/>
    <property name="filters">
        <util:map>
            <entry key="authc" value-ref="securityAuthcFilter"/>
        </util:map>
    </property>
    <property name="filterChainDefinitions"> 
      <value> 
         /logout.do*=anon 
         /casticketerror.do*=anon 
          
         # 權(quán)限配置示例
         /security/account/view.do=authc,perms[SECURITY_ACCOUNT_VIEW] 
          
         /** = authc 
      </value> 
   </property> 
</bean>


這樣再訪問 /** 目錄的時候就會走到 SecurityAuthcFilter 這個類做認(rèn)證了。

因為這個類創(chuàng)建的token 是SecurityToken,默認(rèn)的realm 處理不了,

所以我們還要 定義自己的realm:


 

public class SecurityRealm extends AuthorizingRealm {
   private static Logger logger = LoggerFactory.getLogger(SecurityRealm.class);

   // @Autowired
   // private ISecurityDelegate securityDelegate;
   // @Autowired
   // private ILoginLogDelegate loginLogDelegate;
   @Autowired
   private SecurityService securityService;
   /**
    * 是否啟用驗證碼
    */
   private boolean isCaptchaEnable = false;

   /**
    * 登錄錯誤的異常信息:驗證碼錯誤異常
    */
   public static final String INCORRECT_CAPTCHA_EXCEPTION_MSG = "驗證碼錯誤!";

   /**
    * 登錄錯誤的異常信息:密碼錯誤異常
    */
   public static final String INCORRECT_PASSWORD_USERNAME_EXCEPTION_MSG = "用戶名或密碼錯誤!";

   /**
    * 登錄錯誤的異常信息:密碼過期異常
    */
   public static final String INACTIVE_PASSWORD_EXCEPTION_MSG = "密碼已過期,請聯(lián)系管理員!";

   /**
    * 登錄錯誤的異常信息:未知異常
    */
   public static final String ACCOUNT_UNKNOWN_EXCEPTION_MSG = "未知系統(tǒng)異常!";

   /**
    * 用戶、員工正常狀態(tài)取值
    */
   private static final String STATUS_NORMAL = "A";

   @Override
   protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
      SysUserDTO sysUser = (SysUserDTO) principals.fromRealm(getName()).iterator().next();
      if (sysUser == null) {
         logger.info("獲取鑒權(quán)信息:無法獲得登錄用戶信息");
         return null;
      }
      try {
         logger.info("獲取鑒權(quán)信息:開始獲取登錄用戶【{}】鑒權(quán)信息", sysUser.getLoginName());
         SimpleAuthorizationInfo info = securityService.doGetAuthorizationInfo(sysUser);
         logger.info("獲取鑒權(quán)信息:成功獲取登錄用戶【{}】鑒權(quán)信息", sysUser.getLoginName());
         return info;
      } catch (SysException e) {
         e.printStackTrace();
         logger.error("獲取鑒權(quán)信息:獲取登錄用戶【{}】鑒權(quán)信息時發(fā)生異常:{}", sysUser.getLoginName(), e.getErrMsg());
         throw new AccountUnknownException(e.getErrMsg());
      }
   }

   /**
    * 獲得用戶認(rèn)證信息
    * 
    * @param authenticationToken
    *            用戶登錄的token
    * @return 用戶認(rèn)證信息
    * @throws AuthenticationException
    *             用戶認(rèn)證異常
    */
   @Override
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
      SecurityToken token = (SecurityToken) authenticationToken;
      Session session = SecurityUtils.getSubject().getSession();

      logger.debug("獲取認(rèn)證信息:開始獲取登錄用戶【{}】認(rèn)證信息", token.getUsername());
      /**
       * 驗證碼校驗
       */
      if (isCaptchaEnable) {
         if (!StringUtils.equalsIgnoreCase(token.getCaptcha(), token.getCaptchaSession())) {
            throw new IncorrectCaptchaException(INCORRECT_CAPTCHA_EXCEPTION_MSG);
         }
         logger.debug("獲取認(rèn)證信息:登錄用戶【{}】通過驗證碼校驗", token.getUsername());
      }

      /**
       * 登錄帳戶信息校驗(校驗帳戶是否存在,以及校驗帳戶狀態(tài))
       */
      logger.debug("獲取認(rèn)證信息:開始數(shù)據(jù)庫驗證登錄用戶【{}】信息", token.getUsername());
      SysUserDTO sysUser = null;
      try {
         sysUser = securityService.doGetAuthenticationInfo(token.getUsername());
      } catch (Exception e) {
         e.printStackTrace();
         logger.error("獲取認(rèn)證信息:獲取登錄用戶【{}】鑒權(quán)信息時發(fā)生異常:{}", token.getUsername(), e.getMessage());
         throw new AccountUnknownException(ACCOUNT_UNKNOWN_EXCEPTION_MSG);
      }
      if (sysUser == null) {
         logger.debug("獲取認(rèn)證信息:登錄用戶【{}】不存在", token.getUsername());
         throw new AccountNotFoundException(INCORRECT_PASSWORD_USERNAME_EXCEPTION_MSG);
      }
      if (!StringUtils.equals(STATUS_NORMAL, sysUser.getSts()) || !StringUtils.equals(STATUS_NORMAL, sysUser.getSts())) {
         logger.debug("獲取認(rèn)證信息:登錄用戶【{}】狀態(tài)異常", token.getUsername());
         throw new AccountStatusException(INCORRECT_PASSWORD_USERNAME_EXCEPTION_MSG);
      }
      if (!StringUtils.equals(String.copyValueOf(token.getPassword()), sysUser.getPassword())) {
         logger.debug("獲取認(rèn)證信息:登錄用戶【{}】密碼錯誤", token.getUsername());
         throw new IncorrectPasswordException(INCORRECT_PASSWORD_USERNAME_EXCEPTION_MSG);
      }

      CacheManager cacheManager = CacheManager.getInstance();
      String inactiveFlag = (String) cacheManager.get(ConstantsUtils.CACHE_SYSTEM + ".table.cache.idvalue.sysconfig", "INACTIVEL_FLAG");
      if (StringUtils.isNotBlank(inactiveFlag) && inactiveFlag.equals("Y")) {
         if (sysUser.getPwdInactiveTime() != null) {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            try {
               Date startDate = df.parse(sysUser.getPwdInactiveTime());
               Date endDate = df.parse(df.format(new Date()));
               long day = (startDate.getTime() - endDate.getTime()) / (24 * 60 * 60 * 1000);
               session.setAttribute("inactiveDays", day);

               if (df.parse(sysUser.getPwdInactiveTime()).getTime() < df.parse(df.format(new Date())).getTime()) {
                  throw new InactivePasswordException(INACTIVE_PASSWORD_EXCEPTION_MSG);
               }
            } catch (ParseException e) {
               e.printStackTrace();
            }
         }
      }
      logger.debug("獲取認(rèn)證信息:完成數(shù)據(jù)庫驗證登錄用戶【{}】信息", token.getUsername());

      /*
       * try { LoginLog loginLog = new LoginLog();
       * loginLog.setSysUserId(sysUser.getSysUserId());
       * loginLog.setIpAddr(token.getHost()); loginLog.setMacAddr(null);
       * loginLog = loginLogService.insert(loginLog);
       * session.setAttribute("loginLogId", loginLog.getLoginLogId()); } catch
       * (SysException e) { e.printStackTrace(); } catch (AppException e) {
       * e.printStackTrace(); }
       */
      logger.debug("獲取認(rèn)證信息:記錄登錄用戶【{}】日志", token.getUsername());
      return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), getName());
   }

   /**
    * 設(shè)置是否啟用校驗碼
    * 
    * @param captchaEnable
    *            是否啟用校驗碼
    */
   public void setCaptchaEnable(boolean captchaEnable) {
      isCaptchaEnable = captchaEnable;
   }
}


配置realm:

<bean id="securityRealm" class="com.credithc.scs.security.SecurityRealm">
    <property name="captchaEnable" value="true"/>
    <property name="cacheManager" ref="securityCacheManager"/>
</bean>

<!-- 創(chuàng)建Shiro的securityManager,并設(shè)置了realm和cacheManager兩個關(guān)鍵屬性 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="securityRealm"/>
</bean>

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    精品熟女少妇av免费久久野外| 免费国产成人性生活生活片| 天海翼精品久久中文字幕| 九九热视频免费在线视频| 99久久精品国产日本| 日韩欧美第一页在线观看| 91欧美一区二区三区成人| 欧美高潮喷吹一区二区| 欧美日韩欧美国产另类| 欧美日韩免费黄片观看| 日本中文在线不卡视频| 欧美午夜一区二区福利视频| 日本少妇三级三级三级| 国产一区日韩二区欧美| 日韩日韩日韩日韩在线| 欧美不雅视频午夜福利| 98精品永久免费视频| 亚洲欧美日韩在线中文字幕| 成人精品一级特黄大片| 亚洲精品欧美精品一区三区| 在线免费观看黄色美女| 亚洲高清一区二区高清| av在线免费观看在线免费观看| 久久久免费精品人妻一区二区三区 | 精品丝袜一区二区三区性色| 日本高清一区免费不卡| 亚洲欧美日韩网友自拍| 欧美一区二区在线日韩| 欧美亚洲三级视频在线观看| 中文字幕一区二区免费| 国产中文字幕久久黄色片| 欧美在线观看视频三区| 欧美色婷婷综合狠狠爱| 亚洲专区中文字幕在线| 女厕偷窥一区二区三区在线| 欧美六区视频在线观看| 精品视频一区二区三区不卡| 在线观看国产午夜福利| 激情五月天深爱丁香婷婷| 日韩毛片视频免费观看| 国产日产欧美精品视频|