shiro登錄 加驗證碼校驗

  • 驗證碼采用一個博客上的驗證碼 點擊跳轉(zhuǎn)
  • 采用action的形式獲取驗證碼,并把驗證碼存入到shiro管理的session中
public void getGifCode(HttpServletResponse response,HttpServletRequest request){
    try {
        response.setHeader("Pragma", "No-cache");  
        response.setHeader("Cache-Control", "no-cache");  
        response.setDateHeader("Expires", 0);  
        response.setContentType("image/gif");  
        /**
         * gif格式動畫驗證碼
         * 寬,高,位數(shù)。
         */
        Captcha captcha = new GifCaptcha(146,42,4);
        //輸出
        ServletOutputStream out = response.getOutputStream();
        captcha.out(out);
        out.flush();
       //存入Shiro會話session  
        System.out.println( captcha.text().toLowerCase());
        TokenManager.setVal2Session(VerifyCodeUtils.V_CODE, captcha.text().toLowerCase());  
    } catch (Exception e) {
        LoggerUtils.fmtError(getClass(),e, "獲取驗證碼異常:%s",e.getMessage());
    }
}
  • 驗證碼驗證的 Shiro 過濾器
public class JCaptchaValidateFilter extends AccessControlFilter{

    /**
     * 是否開啟驗證碼驗證   默認true
     */
    private boolean jcaptchaEbabled = true;

    /**
     * 前臺提交的驗證碼參數(shù)名
     */
    private String jcaptchaParam = "jcaptchaCode";

    /**
     * 驗證失敗后存儲到的屬性名
     */
    private String failureKeyAttribute = "shiroLoginFailure";

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object o) throws Exception {
        //1、設(shè)置驗證碼是否開啟屬性,頁面可以根據(jù)該屬性來決定是否顯示驗證碼
        request.setAttribute("jcaptchaEbabled", jcaptchaEbabled);

        HttpServletRequest httpRequest = WebUtils.toHttp(request);

        //2、判斷驗證碼是否禁用 或不是表單提交(允許訪問)
        if (jcaptchaEbabled == false || !"post".equalsIgnoreCase(httpRequest.getMethod())) {
            return true;
        }

        //表單提交,校驗驗證碼的正確性
        String storedCode = getSubject(request, response).getSession().getAttribute(Constatns.VERIFYCODE).toString();
        String currentCode = httpRequest.getParameter(jcaptchaParam);

        return StringUtils.equalsIgnoreCase(storedCode, currentCode);
    }
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse servletResponse) throws Exception {
        //如果驗證碼失敗了,存儲失敗 key 屬性
        request.setAttribute(failureKeyAttribute, "jCaptcha.error");
        return true;
    }
    public String getFailureKeyAttribute() {
        return failureKeyAttribute;
    }
    public void setFailureKeyAttribute(String failureKeyAttribute) {
        this.failureKeyAttribute = failureKeyAttribute;
    }
    public String getJcaptchaParam() {
        return jcaptchaParam;
    }
    public void setJcaptchaParam(String jcaptchaParam) {
        this.jcaptchaParam = jcaptchaParam;
    }
    public boolean isJcaptchaEbabled() {
        return jcaptchaEbabled;
    }
    public void setJcaptchaEbabled(boolean jcaptchaEbabled) {
        this.jcaptchaEbabled = jcaptchaEbabled;
    }
}
  • MyFormAuthenticationFilter ,表單提交時,先驗證驗證碼,如果驗證成功再走登錄流程

用于驗證碼驗證的 Shiro 攔截器在用于身份認證的攔截器之前運行;但是如果驗證碼驗證攔截器失敗了,就不需要進行身份認證攔截器流程了;所以需要修改下如FormAuthenticationFilter 身份認證攔截器,當驗證碼驗證失敗時不再走身份認證攔截器。

public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if(request.getAttribute(getFailureKeyAttribute()) != null) {
            return true;
        }
        return super.onAccessDenied(request, response);
    }
}
  • 配置文件的配置
<!-- 基于form表單的身份驗證過濾器 帶有驗證碼的過濾-->
<bean id="myformAuthenticationFilter" class="com.nanc.core.shiro.filter.MyFormAuthenticationFilter">
    <property name="usernameParam" value="username"/>
    <property name="passwordParam" value="password"/>
    <property name="rememberMeParam" value="rememberMe"/>
    <property name="loginUrl" value="/login"/>
    <property name="failureKeyAttribute" value="shiroLoginFailure"/>
</bean>

<!-- 驗證碼的過濾器 -->
<bean id="jCaptchaFilter" class="com.nanc.core.shiro.filter.JCaptchaValidateFilter">
    <property name="failureKeyAttribute" value="shiroLoginFailure"/>
    <property name="jcaptchaParam" value="jcaptchaCode"/><!-- 頁面的參數(shù)名-->
    <property name="jcaptchaEbabled" value="true"/>
</bean>

<!-- Shiro的Web過濾器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/login"/>
    <property name="filters">
        <map>
            <!--<entry key="authc" value-ref="formAuthenticationFilter"/>-->
            <entry key="authc" value-ref="myformAuthenticationFilter"/>
            <entry key="jcaptcha" value-ref="jCaptchaFilter"/>
            <entry key="sysUser" value-ref="sysUserFilter"/>
            <entry key="kickout" value-ref="kickoutFilter"/>
            <!--添加ssl支持-->
            <!--<entry key="ssl" value-ref="sslFilter"/>-->
            <!-- 結(jié)束ssl支持-->
        </map>
    </property>
    <property name="filterChainDefinitions">
        <value>
            /login=jcaptcha,authc
            /loginDialog=authc
            /logout=logout
            /authenticated=authc
            /dwz_jui/**=anon
            /common/**=anon
            /**=kickout,user,sysUser
        </value>
    </property>
</bean>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,725評論 25 709
  • 三森被德井推著,終于一臉視死如歸地踏入影棚休息室的時候,正撞見新田和已經(jīng)上好試妝的內(nèi)田有說有笑地談著什么。 “誒?...
    Azure_潮生閱讀 313評論 0 0
  • 靜子出水亭亭立,發(fā)秀密瀑香隨飄。多少慕心癡醉漢,夜黑夢發(fā)仙影眸。惜兮貌美卻步止,只怨姑娘啞無聲。自生卻失言難破,盡...
    南溪向南北歌流海閱讀 256評論 0 0
  • 七月七七夕節(jié) 牛郎要把織女約 六毋村李大姐 生日就在七夕節(jié) 兒子媳婦在省城 回家拜壽忙商量 女:“你媽過壽你去...
    歡呼收割一閱讀 447評論 28 25

友情鏈接更多精彩內(nèi)容