shiro-登陆增加一个字段

2 篇文章 0 订阅

验证码是为了区分人与电脑,防止电脑代替人冲击系统。在伟大的中国人民人工验证的海洋面前,验证码完全不是个事。
不过一般不是特别热门的系统是不会有人雇佣人民海洋来人工识别验证码的,所有我们的系统还是需要加入验证码机制。
在Java Web系统中验证码世界已经很多种的实现,有些很大很复杂,有些没有维护了,有些验证码人也认证不出来。。。比较合适用的就是Jcaptcha和Kcaptcha。

Captcha使用都是很简单的,通过专门的servlet生成图片,把图片的数据保存在session中,最后在处理请求的servlet中验证图片输入是否正常。当然一般都会有很多配置,因为Captcha生成图片需要时间,所有需要谨慎配置。

Kcaptcha与Shiro登录结合使用

1. Web.xml

<servlet>
        <servlet-name>Kaptcha</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
        <servlet-name>Kaptcha</servlet-name>
        <url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2. 登录Jsp

<%
            String error = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
            if(error != null){

                if(error.contains("IncorrectCaptchaException")){
                    out.print("用户输入验证码错误.");
                }
                else{
                    out.print("登录失败,请重试.");
                }
            }
        %>      
<form action="">
    Username: <input type="text" name="username"/> <br/>
   Password: <input type="password" name="password"/>
    <img src="kaptcha.jpg" /> <input type="text" name="kaptcha" value="" />
</form>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3. Shiro登录Filter

a. 扩展登录UsernamePasswordToken,加入kaptcha字段

public class CaptchaAuthenticationToken extends UsernamePasswordToken{  

    private String kaptcha;  

    public CaptchaAuthenticationToken (){}  

    public CaptchaAuthenticationToken (String username, String password,
            boolean rememberMe, String host, String captcha) {
        super(username, password, rememberMe, host);
        this.captcha = captcha;
    } 

    public void setKaptcha(String kaptcha){  
        this.kaptcha= kaptcha;  
    }  

    public String getKaptcha(){  
        return this.kaptcha;  
    }  
  }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

b. 扩展formAuthenticationFilter,检验用户输入验证码

public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter {

    private String captchaParam = "kaptcha";

    public String getCaptchaParam() {
        return captchaParam;
    }

    protected String getCaptcha(ServletRequest request) {
        return WebUtils.getCleanParam(request, getCaptchaParam());
    }

    @Override
    protected AuthenticationToken createToken(ServletRequest request,
            ServletResponse response) {
        String username = getUsername(request);
        String password = getPassword(request);
        String captcha = getCaptcha(request);
        boolean rememberMe = isRememberMe(request);
        String host = getHost(request);
        return new CaptchaAuthenticationToken(username, password, rememberMe,
                host, captcha);
    }

   // 验证码校验
    protected void doCaptchaValidate(HttpServletRequest request, CaptchaAuthenticationToken token) {
        String captcha = (String) request.getSession().getAttribute(ShiroConstant.CAPTCHA_SESSION_KEY);

        if (StringUtil.isEmpty(token.getCaptcha()) || !token.getCaptcha().equalsIgnoreCase(captcha)) {
            /* 定义IncorrectCaptchaException,shiro显示Exception class name作为error信息 */
            throw new IncorrectCaptchaException("验证码错误!");
        }
    }

    /*
      protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
        String className = ae.getClass().getName();
        request.setAttribute(getFailureKeyAttribute(), className);
    }
    */
    // 认证
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        CaptchaAuthenticationToken token = createToken(request, response);

        try {
            doCaptchaValidate((HttpServletRequest) request, token);

            Subject subject = getSubject(request, response);
            subject.login(token);

            return onLoginSuccess(token, subject, request, response);
        } catch (AuthenticationException e) {
            return onLoginFailure(token, e, request, response);
        }
    }
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

c. 增加 IncorrectCaptchaException

public class IncorrectCaptchaException extends AuthenticationException {

  public IncorrectCaptchaException() {
    super();
  }

  public IncorrectCaptchaException(String message, Throwable cause) {
    super(message, cause);
  }

  public IncorrectCaptchaException(String message) {
    super(message);
  }

  public IncorrectCaptchaException(Throwable cause) {
    super(cause);
  }
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

d.修改Shiro配置文件,让/kaptcha.jpg的访问变成匿名

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/login.jsp" />
        <property name="successUrl" value="/" />
        <property name="filters">
            <map>
                <!-- 启用验证码检验 -->
                <entry key="authc" value-ref="captchaFormAuthenticationFilter"/>
            </map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                /kaptcha.jpg = anon
                /styles/** = anon
                /login = authc
                /logout = logout
                /** = user
            </value>
        </property>
    </bean>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值