zoukankan      html  css  js  c++  java
  • Shiro第六篇【验证码、记住我】

    验证码

    在登陆的时候,我们一般都设置有验证码,但是我们如果使用Shiro的话,那么Shiro默认的是使用FormAuthenticationFilter进行表单认证。

    而我们的验证校验的功能应该加在FormAuthenticationFilter中,在认证之前进行验证码校验

    FormAuthenticationFilter是Shiro默认的功能,我们想要在FormAuthenticationFilter之前进行验证码校验,就需要继承FormAuthenticationFilter类,改写它的认证方法

    自定义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配置文件中配置我们这个自定义类的。

    由于这是我们自定义的,因此我们并不需要用户名就使用username,密码就使用password,这个也是我们可以自定义的

    
    <!-- 自定义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中获取获取信息,从而给用户对应的提示

    
    
        @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中取出身份信息实现自动登陆。

    想要实现这个功能,我们的认证信息需要实现Serializable接口

    
    
    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
    
  • 相关阅读:
    微信小程序登录
    cURL error 60: SSL certificate problem: unable to get local issuer certificate 报错解决
    MyBatis学习之一----基础了解
    web工程和java工程的区别
    StringUtils的实用功能
    SpringMVC-----部分功能学习
    SpringMVC之国际化
    SpringMVC
    web.xml配置详解
    Hibernate学习-----遇到的相关问题
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7554342.html
Copyright © 2011-2022 走看看