Shiro第六篇【驗證碼、記住我】

驗證碼

在登錄的時候,咱們通常都設置有驗證碼,可是咱們若是使用Shiro的話,那麼Shiro默認的是使用FormAuthenticationFilter進行表單認證。javascript

而咱們的驗證校驗的功能應該加在FormAuthenticationFilter中,在認證以前進行驗證碼校驗css

FormAuthenticationFilter是Shiro默認的功能,咱們想要在FormAuthenticationFilter以前進行驗證碼校驗,就須要繼承FormAuthenticationFilter類,改寫它的認證方法java

自定義Form認證類

public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {

    //原FormAuthenticationFilter的認證方法
    @Override
    protected boolean onAccessDenied(ServletRequest request,
            ServletResponse response) throws Exception {
        //在這裏進行驗證碼的校驗

        //從session獲取正確驗證碼
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpSession session =httpServletRequest.getSession();
        //取出session的驗證碼(正確的驗證碼)
        String validateCode = (String) session.getAttribute("validateCode");

        //取出頁面的驗證碼
        //輸入的驗證和session中的驗證進行對比 
        String randomcode = httpServletRequest.getParameter("randomcode");
        if(randomcode!=null && validateCode!=null && !randomcode.equals(validateCode)){
            //若是校驗失敗,將驗證碼錯誤失敗信息,經過shiroLoginFailure設置到request中
            httpServletRequest.setAttribute("shiroLoginFailure", "randomCodeError");
            //拒絕訪問,再也不校驗帳號和密碼 
            return true; 
        }
        return super.onAccessDenied(request, response);
    }


}

配置自定義類

咱們編寫完自定義類之後,是須要在Shiro配置文件中配置咱們這個自定義類的。web

因爲這是咱們自定義的,所以咱們並不須要用戶名就使用username,密碼就使用password,這個也是咱們能夠自定義的apache

<!-- 自定義form認證過慮器 -->
<!-- 基於Form表單的身份驗證過濾器,不配置將也會註冊此過慮器,表單中的用戶帳號、密碼及loginurl將採用默認值,建議配置 -->
    <bean id="formAuthenticationFilter" class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter ">
        <!-- 表單中帳號的input名稱 -->
        <property name="usernameParam" value="username" />
        <!-- 表單中密碼的input名稱 -->
        <property name="passwordParam" value="password" />
 </bean>

在Shiro的bean中注入自定義的過濾器安全

 <!-- 自定義filter配置 --> <property name="filters"> <map> <!-- 將自定義 的FormAuthenticationFilter注入shiroFilter中--> <entry key="authc" value-ref="formAuthenticationFilter" /> </map> </property> 

在咱們的Controller添加驗證碼錯誤的異常判斷,從咱們的Controller就能夠發現,爲何咱們要把錯誤信息存放在request域對象shiroLoginFailure,由於咱們得在Controller中獲取獲取信息,從而給用戶對應的提示markdown

 @RequestMapping("login") public String login(HttpServletRequest request)throws Exception{ //若是登錄失敗從request中獲取認證異常信息,shiroLoginFailure就是shiro異常類的全限定名 String exceptionClassName = (String) request.getAttribute("shiroLoginFailure"); //根據shiro返回的異常類路徑判斷,拋出指定異常信息 if(exceptionClassName!=null){ if (UnknownAccountException.class.getName().equals(exceptionClassName)) { //最終會拋給異常處理器 throw new CustomException("帳號不存在"); } else if (IncorrectCredentialsException.class.getName().equals( exceptionClassName)) { throw new CustomException("用戶名/密碼錯誤"); } else if("randomCodeError".equals(exceptionClassName)){ throw new CustomException("驗證碼錯誤 "); }else { throw new Exception();//最終在異常處理器生成未知錯誤 } } //此方法不處理登錄成功(認證成功),shiro認證成功會自動跳轉到上一個請求路徑 //登錄失敗還到login頁面 return "login"; }

這裏寫圖片描述

<TR>
        <TD>驗證碼:</TD>
        <TD><input id="randomcode" name="randomcode" size="8" /> <img  id="randomcode_img" src="${baseurl}validatecode.jsp" alt="" width="56" height="20" align='absMiddle' /> <a  href=javascript:randomcode_refresh()>刷新</a></TD>
    </TR>

記住我

Shiro還提供了記住用戶名和密碼的功能cookie

用戶登錄選擇「自動登錄」本次登錄成功會向cookie寫身份信息,下次登錄從cookie中取出身份信息實現自動登錄。session

想要實現這個功能,咱們的認證信息須要實現Serializable接口app

public class ActiveUser implements java.io.Serializable { private String userid;//用戶id(主鍵) private String usercode;// 用戶帳號 private String username;// 用戶名稱 private List<SysPermission> menus;// 菜單 private List<SysPermission> permissions;// 權限 }

配置rememeber管理器

<!-- rememberMeManager管理器,寫cookie,取出cookie生成用戶信息 -->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <property name="cookie" ref="rememberMeCookie" />
    </bean>
    <!-- 記住我cookie -->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!-- rememberMe是cookie的名字 -->
        <constructor-arg value="rememberMe" />
        <!-- 記住我cookie生效時間30天 -->
        <property name="maxAge" value="2592000" />
    </bean>

注入到安全管理器類上

 <!-- securityManager安全管理器 --> <bean id="securityManager"~~~···· <property name="cacheManager" ref="cacheManager"/> <!-- 注入session管理器 --> <property name="sessionManager" ref="sessionManager" /> <!-- 記住我 --> <property name="rememberMeManager" ref="rememberMeManager"/> </bean> 

配置頁面的input名稱:

<tr>
                <TD></TD>
                <td><input type="checkbox" name="rememberMe" />自動登錄</td>
            </tr>

若是設置了「記住我」,那麼訪問某些URL的時候,咱們就不須要登錄了。將記住我便可訪問的地址配置讓UserFilter攔截。

<!-- 配置記住我或認證經過能夠訪問的地址 -->
        /index.jsp  = user
        /first.action = user
        /welcome.jsp = user
相關文章
相關標籤/搜索