结合springMVC,shiro,redis,kaptcha进行验证码登录完整随笔

自己在做项目的时候总结的配置全部流程,用作记录也希望能帮助大家。

一、进行kaptha的依赖配置

1  <!--验证码生成工具-->
2         <dependency>
3             <groupId>com.github.penggle</groupId>
4             <artifactId>kaptcha</artifactId>
5             <version>2.3.2</version>
6         </dependency>

二、web.xml配置,我们只需要简单配置一个 Servlet,页面通过 IMG 标签就可以展现图形验证码。

<servlet>
        <servlet-name>Kaptcha</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
        <init-param>
        <param-name>kaptcha.image.width</param-name>
        <param-value>200</param-value>
        </init-param>
        <init-param>
        <param-name>kaptcha.image.height</param-name>
        <param-value>50</param-value>
        </init-param>
        <init-param>
        <param-name>kaptcha.textproducer.char.length</param-name>
        <param-value>4</param-value>
        </init-param>
        <init-param>
        <param-name>kaptcha.noise.impl</param-name>
        <param-value>com.google.code.kaptcha.impl.NoNoise</param-value>
        </init-param>
        <init-param>
        <param-name>kaptcha.session.key</param-name>
        <param-value>rand</param-value>
        </init-param>
</servlet>
<servlet-mapping>
        <servlet-name>Kaptcha</servlet-name>
        <url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>

三、扩展 UsernamePasswordTokenShiro 表单认证,页面提交的用户名密码等信息,用 UsernamePasswordToken 类来接收,很容易想到,要接收页面验证码的输入,我们需要扩展此类:

package com.caa.shiro.filter;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;

public class CaptchaUsernamePasswordToken extends UsernamePasswordToken {
    //验证码字符串
    private String captcha;

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

    public String getCaptcha() {
        return captcha;
    }

    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }

}

四、

扩展 FormAuthenticationFilter

接下来我们扩展 FormAuthenticationFilter 类

这里贴一个全部的扩展方法,不过实际上我使用的是shiro自带的登录验证 后添加的验证码的校验方法(如果也是只需要添加验证码功能那只需要在你的控制层调用doCaptchaValidate方法即可

package com.caa.shiro.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter {
    private static final Logger LOG = LoggerFactory.getLogger(CaptchaFormAuthenticationFilter.class);

    public CaptchaFormAuthenticationFilter() {
    }
    @Override
    /**
     * 登录验证
     */
    protected boolean executeLogin(ServletRequest request,
            ServletResponse response) throws Exception {
        CaptchaUsernamePasswordToken token = createToken(request, response);
        try {
            /*图形验证码验证*/
            doCaptchaValidate((HttpServletRequest) request, token);
            Subject subject = getSubject(request, response);
            subject.login(token);//正常验证
            LOG.info(token.getUsername()+"登录成功");
            return onLoginSuccess(token, subject, request, response);
        }catch (AuthenticationException e) {
            LOG.info(token.getUsername()+"登录失败--"+e);
            return onLoginFailure(token, e, request, response);
        }
    }

    // 验证码校验
    public void doCaptchaValidate(HttpServletRequest request,
            CaptchaUsernamePasswordToken token) {
//session中的图形码字符串
        HttpSession session = request.getSession();
        String captcha = (String)session.getAttribute("rand");
//比对
        if (captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())) {
            throw new IncorrectCaptchaException("验证码错误!");
        }
    }

    @Override
    protected CaptchaUsernamePasswordToken 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 CaptchaUsernamePasswordToken(username,
                password, rememberMe, captcha);
    }

    public static final String DEFAULT_CAPTCHA_PARAM = "captcha";

    private String captchaParam = DEFAULT_CAPTCHA_PARAM;

    public String getCaptchaParam() {
        return captchaParam;
    }

    public void setCaptchaParam(String captchaParam) {
        this.captchaParam = captchaParam;
    }

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

//保存异常对象到request
    @Override
    protected void setFailureAttribute(ServletRequest request,
            AuthenticationException ae) {
        request.setAttribute(getFailureKeyAttribute(), ae);
    }
}

六、前面验证码校验不通过,我们抛出一个异常 IncorrectCaptchaException,此类继承 AuthenticationException,之所以需要扩展一个新的异常类,为的是在页面能更精准显示错误提示信息。

package com.caa.shiro.filter;

import org.apache.shiro.authc.AuthenticationException;

public class IncorrectCaptchaException extends AuthenticationException {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public IncorrectCaptchaException() {
        super();
    }

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

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

    public IncorrectCaptchaException(Throwable cause) {
        super(cause);
    }
}

七、shiro配置(Filter的配置及使用)这段因为我的配置文件东西较多 在网上贴了一段 核心东西都有

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">

    <!-- Shiro Filter 拦截器相关配置 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- securityManager -->
        <property name="securityManager" ref="securityManager" />
        <!-- 登录路径 -->
        <property name="loginUrl" value="/login.jsp" />
        <!-- 登录成功后跳转路径 -->
        <property name="successUrl" value="/pages/index.jsp" />
        <!-- 授权失败跳转路径 -->
        <property name="unauthorizedUrl" value="/login.jsp" />
        <property name="filters">
            <util:map>
                <entry key="authc" value-ref="myAuthenFilter" />
            </util:map>
        </property>
        <!-- 过滤链定义 -->
        <property name="filterChainDefinitions">
            <value>
                /login.jsp = authc
                /pages/* = authc
                /index.jsp* = authc
                /logout.do = logout
                <!-- 访问这些路径必须拥有某种权限 /role/edit/* = perms[role:edit] /role/save = perms[role:edit]
                    /role/list = perms[role:view] -->
            </value>
        </property>
    </bean>

    <!-- 自定义验证拦截器 -->
    <bean id="myAuthenFilter" class="javacommon.shiro.CaptchaFormAuthenticationFilter" />

    <!-- securityManager -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRealm" />
    </bean>

    <!-- <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManager" ref="cacheManager" /> </bean> -->

    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

    <!-- 自定义Realm实现 -->
    <bean id="myRealm" class="javacommon.shiro.CustomRealm">
        <!-- <property name="cacheManager" ref="shiroCacheManager" /> -->
    </bean>
</beans>

八、前台页面(本人用的是html加vue的,不过前天东西不多可以根据自己的页面来修改)

<body class="hold-transition login-page" style="background: black url(statics/images/login-bg.jpg) no-repeat fixed top;">
    <div class="login-box" id="rrapp" style="margin-top: 12%" v-cloak>
      <div class="login-box-body">
          <p class="login-box-msg" style="font-size: 25px;font-weight:bold">中拍协后台管理系统</p>
          <div v-if="error" class="alert alert-danger alert-dismissible">
            <h4 style="margin-bottom: 0px;"><i class="fa fa-exclamation-triangle"></i> {{errorMsg}}</h4>
          </div>
          <div class="form-group has-feedback">
            <input type="text" class="form-control" v-model="username" @keyup.enter="login" placeholder="账号" autofocus>
            <span class="fa fa-user form-control-feedback"></span>
          </div>
          <div class="form-group has-feedback">
            <input type="password" class="form-control" v-model="password" @keyup.enter="login" placeholder="密码">
            <span class="fa fa-lock form-control-feedback"></span>
          </div>
          <div >
            <input type="text" id="code" name="captcha" v-model="captcha" @keyup.enter="login" class="form-control" placeholder="验证码">
        </div>
        <div >
            <img id="codeImg" src="kaptcha.jpg" class="img-responsive" style="display:inline" @click="refreshCaptcha">(看不清<a href="javascript:void(0)" @click="refreshCaptcha" style="display:inline">换一张</a>)
        </div>
          <div class="checkbox">
              <label>
                <input type="checkbox" name="isRememberMe" v-model="isRememberMe">记住我,下次免登陆
              </label>
          </div>
          <div class="row">
            <div class="col-xs-12">
              <button type="button" class="btn btn-block btn-success btn-lg" @click="login">登录</button>
            </div>
          </div>
      </div>
    </div>

    <script type="text/javascript">
        var vm = new Vue({
            el:‘#rrapp‘,
            data:{
                username: ‘‘,
                password: ‘‘,
                captcha: ‘‘,
                error: false,
                errorMsg: ‘‘,
                isRememberMe:false
            },
            beforeCreate: function(){
                if(self != top){
                    top.location.href = self.location.href;
                }
            },
            methods: {
                login: function (event) {
                    var data = "username="+vm.username+"&password="+vm.password+"&isRememberMe="+vm.isRememberMe+"&captcha="+vm.captcha;
                    $.ajax({
                        type: "POST",
                        url: "login",
                        data: data,
                        dataType: "json",
                        success: function(result){
                            if(result.code == 0){//登录成功
                                parent.location.href =‘index.html‘;
                            }else{
                                vm.error = true;
                                vm.errorMsg = result.msg;
                                document.getElementById("codeImg").src="kaptcha.jpg?t=" + Math.random();
                            }
                        }
                    });
                },
                refreshCaptcha: function () {
                    document.getElementById("codeImg").src="kaptcha.jpg?t=" + Math.random();
                }
            }
        });
    </script>
</body>

原文地址:https://www.cnblogs.com/lrx931028/p/9269722.html

时间: 2024-07-30 12:23:56

结合springMVC,shiro,redis,kaptcha进行验证码登录完整随笔的相关文章

springmvc下使用kaptcha做验证码64534sybov

堂辕澳 厝恂镁犭 寥几句聊天便知谈吐不俗.右侧那身份古怪的年轻女子可真是长得灵气裴南苇身为胭脂 这座城池的建造可能称得上前无古人后无来者不但规模犹胜西北第一边城虎头城而且 人钟啜 由坦途官道岔入一条小道便是繁茂成林的芦苇荡王妃以往几年赏景千篇一律下车后就 有个归隐田园的老人在一个大雪纷飞的暮色中步履蹒跚不是前往那仅有娘俩扫墓却也 不光是沙场上建功立业的将领便是文官也都一律下意识抱拳还礼. 战怎么看都噱头十足近期已经挣了江湖人士无数斤的口水唾沫.但底层江湖侠士与绿林 謇查坟锴 锞霭行妹 眺育骠

SpringMVC+Apache Shiro+JPA(hibernate)案例教学(二)基于SpringMVC+Shiro的用户登录权限验证

序: 在上一篇中,咱们已经对于项目已经做了基本的配置,这一篇文章开始学习Shiro如何对登录进行验证. 教学: 一.Shiro配置的简要说明. 有心人可能注意到了,在上一章的applicationContext.xml配置文件中,包含以下配置. <!-- 項目自定义的Realm --> <bean id="shiroDbRealm" class="org.shiro.demo.service.realm.ShiroDbRealm" ><

原创SpringMvc+Mybatis+Redis框架

声明: 本人提供这个 SpringMvc + Mybatis + Redis 的Demo 本着学习的态度,如果有欠缺和不足的地方,给予指正,并且多多包涵 框架运行环境: Maven版本:3.3.9 Eclipse版本:MARS.2 JDK版本:1.8 Tocat版本:8.0.36 框架结构:框架全采用maven管理 所以源码只有180KB左右要是不会Maven就请自行补习 infrastructure:项目名 main:一些顶层的封装 包括了 annotation:自定义注解 实现的类似于shi

SpringMVC+Shiro权限管理【转】

1.权限的简单描述 2.实例表结构及内容及POJO 3.Shiro-pom.xml 4.Shiro-web.xml 5.Shiro-MyShiro-权限认证,登录认证 6.Shiro-applicationContext-shiro.xml 7.HomeController三个JSP文件 什么是权限呢?举个简单的例子:我有一个论坛,注册的用户分为normal用户,manager用户.对论坛的帖子的操作有这些:添加,删除,更新,查看,回复我们规定:normal用户只能:添加,查看,回复manage

Spring MVC 使用kaptcha生成验证码

Spring MVC 使用kaptcha生成验证码 1.下载kaptcha-2.3.2.jar(或直接通过该文章附件下载) http://code.google.com/p/kaptcha/downloads/list kaptcha-2.3.2-jdk14.jar kaptcha-2.3.2.jar ? 向spring.xml中添加bean <bean id="captchaProducer" class="com.google.code.kaptcha.impl.D

SpringMVC+Shiro权限管理

SpringMVC+Shiro权限管理 什么是权限呢?举个简单的例子: 我有一个论坛,注册的用户分为normal用户,manager用户.对论坛的帖子的操作有这些:添加,删除,更新,查看,回复我们规定:normal用户只能:添加,查看,回复manager用户可以:删除,更新 normal,manager对应的是角色(role)添加,删除,更新等对应的是权限(permission) 我们采用下面的逻辑创建权限表结构(不是绝对的,根据需要修改) 一个用户可以有多种角色(normal,manager,

springboot+shiro+redis(单机redis版)整合教程-续(添加动态角色权限控制)

相关教程: 1. springboot+shiro整合教程 2. springboot+shiro+redis(单机redis版)整合教程 3. springboot+shiro+redis(集群redis版)整合教程 参考此教程前请先阅读 2.springboot+shiro+redis(单机redis版)整合教程,此教程是在其基础上进行修改添加动态角色权限的. 本教程整合环境: java8 maven redis(单机) 开发工具: idea 版本: springboot 1.5.15.RE

SpringMVC+Shiro整合配置文件详解

在项目中xml文件的配置是必不可少的,特别是SpringMVC框架.但是几乎所有项目的配置都是大同小异,很多人都是直接复制黏贴了事,不少人对其具体含义及用途都不甚全知.本片文章将正对项目中常用的框架SpringMVC+Shiro进行整合,并对其中关键和部分常识性问题进行注释讲解,方便在以后的项目编写中查阅和熟悉. 1.web.xml文件的配置 所有javaweb项目第一步要做的就是对web.xml文件进行配置. 1 <?xml version="1.0" encoding=&qu

springmvc整合redis架构搭建实例

新换环境,又有新东西可以学习了,哈皮! 抽空学习之余看了一下redis,个人对Springmvc的爱是忠贞不渝,所以整理了一下Springmvc整合redis的环境搭建.分享学习. 第一步: 创建maven项目: 实例pom.xml内容如下 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns