Shiro 结合 kcaptcha实现登录验证

验证码是为了区分人与电脑,防止电脑代替人冲击系统。在伟大的中国人民人工验证的海洋面前,验证码完全不是个事。

不过一般不是特别热门的系统是不会有人雇佣人民海洋来人工识别验证码的,所有我们的系统还是需要加入验证码机制。

在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>

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>

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;
    }
  }

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);
        }
    }
}

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);
  }
}

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>
时间: 02-07

Shiro 结合 kcaptcha实现登录验证的相关文章

Shiro安全框架入门篇(登录验证实例详解与源码)

一.Shiro框架简单介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和JavaEE项目中都可以使用.它主要用来处理身份认证,授权,企业会话管理和加密等.Shiro的具体功能点如下: (1)身份认证/登录,验证用户是不是拥有相应的身份: (2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色.或者细粒度的验证某个用户对某个资源是否具有某个权限: (3)会话管理,即用户登录

SpringMVC+Apache Shiro+JPA(hibernate)案例教学(三)给Shiro登录验证加上验证码

序: 给Shiro加入验证码,有多种方式,当然你也可以通过继承修改FormAuthenticationFilter类,通过Shiro去验证验证码.具体实现请百度: 应用Shiro到Web Application(验证码实现) 而今天我要说的,既然使用的SpringMVC,为什么不直接在Controller中就处理验证码验证,让事情变的更简单一点呢? 一.新建ValidateCode.java验证码工具类 package org.shiro.demo.util; import java.util.

简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)

前言: shiro因为其简单.可靠.实现方便而成为现在最常用的安全框架,那么这篇文章除了会用简洁明了的方式讲一下基于spring的shiro详细配置和登录注销功能使用之外,也会根据惯例在文章最后总结一下shiro的大致配置使用流程,希望本篇文章能够后能给大家一种原来shiro这么简单的错觉感觉. 注意:该篇文章的开始是建立在一个完备的spring+mybatis的开发环境中,除了shiro之外的配置基本不会涉及到.做好自己--eguid原创文章 一.依赖的jar包 本篇文章使用shiro-1.4

spring boot + shiro 登录验证

form提交 <form th:action="@{/login}" method="POST"> <div class="form-group has-feedback"> <input name="username" type="text" class="form-control" placeholder="用户账户" require

Shiro自定义realm实现密码验证及登录、密码加密注册、修改密码的验证

一:先从登录开始,直接看代码 @RequestMapping(value="dologin",method = {RequestMethod.GET, RequestMethod.POST},produces="text/html;charset=UTF-8") @ResponseBody public ResultJson systemUserdologin(XXX xxx,HttpServletRequest request,HttpServletRespons

Jeesite单点登录集成cas另加自定义登录验证

Jeesite单点登录集成Cas另加自定义登录验证 JeeSite是基于多个优秀的开源项目,高度整合封装而成的高效,高性能,强安全性的 开源 Java EE快速开发平台. Cas主要是用来解决多应用之间统一登陆认证,无需用户在同一公司多应用之间重复登陆.例如阿里巴巴中淘宝.天猫,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. Cas基础 服务端 服务端cas-server-webapp-4.0.0.war,服务器端程序一般不用我们完成,但需要做一点小小的修改,cas的服务

项目一:第十二天 1、常见权限控制方式 2、基于shiro提供url拦截方式验证权限 3、在realm中授权 5、总结验证权限方式(四种) 6、用户注销7、基于treegrid实现菜单展示

1 课程计划 1. 常见权限控制方式 2. 基于shiro提供url拦截方式验证权限 3. 在realm中授权 4. 基于shiro提供注解方式验证权限 5. 总结验证权限方式(四种) 6. 用户注销 7. 基于treegrid实现菜单展示 2 常见的权限控制方式 2.1 url拦截实现权限控制 shiro基于过滤器实现的   2.2 注解方式实现权限控制 底层:代理技术     3 基于shiro的url拦截方式验权   <!-- 配置过滤器工厂 --> <bean id="

分享知识-快乐自己:注册用户密码加密、登录验证及权限验证

***********************以下内容仅作为参考使用:********************************* 1.用户注册时,将用户设置的密码加密后存入数据库中(显然密码不能简单地用md5加密一次或者干脆不加密,这些都是会暴露用户隐私的,甚至是触动用户的利益): 加密密码: //生成盐(部分,需要存入数据库中) String random=new SecureRandomNumberGenerator().nextBytes().toHex(); //将原始密码加盐(

ThinkPHP之登录验证

我比较懒,估计写的不是很完整 <?php /** * Created by dreamcms. * User: Administrator * Date: 2016/9/5 * Time: 17:15 */ namespace Admin\Controller; use Think\Controller; class LoginController extends CommonController{ //视图显示 public function Login(){ $this->display(