shiro表单的验证 自定义FormAuthenticationFilter

来源:互联网 发布:python执行exe程序 编辑:程序博客网 时间:2024/05/16 19:10
验证码思路;shiro使用FormAuthenticationFilter进行表单认证,验证校验的功能应该加在FormAuthenticationFilter中,在认证之前进行验证码校验。需要写FormAuthenticationFilter的子类,继承FormAuthenticationFilter,改写它的认证方法,在认证之前进行验证码校验。自定义FormAuthenticationFilter[html] view plain copypackage cn.me.ssm.shiro;    import javax.servlet.ServletRequest;  import javax.servlet.ServletResponse;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpSession;    import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;    public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {        @Override      protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {          // 在这里进行验证码的校验          HttpServletRequest httpServletRequest = (HttpServletRequest) request;          HttpSession session = httpServletRequest.getSession();            // 取出验证码          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);      }  }  spirng-shiro.xml修改[html] view plain copy<!-- Shiro过滤器 -->      <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">          <!-- Shiro的核心安全接口,这个属性是必须的 -->          <property name="securityManager" ref="securityManager" />          <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->          <property name="loginUrl" value="/login.do" />          <!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->          <property name="successUrl" value="/first.do" />          <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面 -->          <property name="unauthorizedUrl" value="/refuse.jsp" />            <!-- 自定义filter配置 -->          <property name="filters">              <map>                  <!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中 -->                  <entry key="authc" value-ref="formAuthenticationFilter" />              </map>          </property>            <!-- Shiro连接约束配置,即过滤链的定义 -->          <property name="filterChainDefinitions">              <value>                  <!-- /** = anon所有url都可以匿名访问 -->                  <!-- 对静态资源设置匿名访问 -->                  /images/** = anon                  /js/** = anon                  /styles/** = anon                  <!-- 验证码,可匿名访问 -->                  /validatecode.jsp = anon                    <!-- 请求 logout.action地址,shiro去清除session -->                  /logout.action = logout                  <!--商品查询需要商品查询权限 ,取消url拦截配置,使用注解授权方式 -->                  <!-- /items/queryItems.action = perms[item:query] -->                  <!-- /** = authc 所有url都必须认证通过才可以访问 -->                  /**=authc                </value>          </property>      </bean>        <!-- 自定义form认证过虑器 -->      <!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->      <bean id="formAuthenticationFilter" class="cn.me.ssm.shiro.CustomFormAuthenticationFilter ">          <!-- 表单中账号的input名称 -->          <property name="usernameParam" value="username" />          <!-- 表单中密码的input名称 -->          <property name="passwordParam" value="password" />      </bean>  在login.do对验证错误 进行解析[html] view plain copy//登陆提交地址,和applicationContext-shiro.xml中配置的loginurl一致      @RequestMapping("/login")      public String login(HttpServletRequest request) throws Exception {            // 如果登录失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名          // 根据shiro返回的异常类路径判断,抛出指定异常信息          String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");          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";      }  记住我用户登陆选择“自动登陆”本次登陆成功会向cookie写身份信息,下次登陆从cookie中取出身份信息实现自动登陆。用户身份实现Java.io.Serializable接口向cookie记录身份信息需要用户身份信息对象实现序列化接口,如下:[html] view plain copypackage cn.me.ssm.po;    import java.io.Serializable;  import java.util.List;    /**   * 用户身份信息   *    * @author Administrator   *   */  public class ActiveUser implements Serializable {      /**       *        */      private static final long serialVersionUID = -60165487594776678L;      private String userid;// 用户id      private String usercode;// 用户帐号      private String username;// 用户名称        private List<SysPermission> menus;// 用户的菜单      private List<SysPermission> permissions;// 权限        public String getUserid() {          return userid;      }        public void setUserid(String userid) {          this.userid = userid;      }        public String getUsercode() {          return usercode;      }        public void setUsercode(String usercode) {          this.usercode = usercode;      }        public String getUsername() {          return username;      }        public void setUsername(String username) {          this.username = username;      }        public List<SysPermission> getMenus() {          return menus;      }        public void setMenus(List<SysPermission> menus) {          this.menus = menus;      }        public List<SysPermission> getPermissions() {          return permissions;      }        public void setPermissions(List<SysPermission> permissions) {          this.permissions = permissions;      }    }  spring-shiro.xml 修改[html] view plain copy<!-- Shiro过滤器 -->  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">      <!-- Shiro的核心安全接口,这个属性是必须的 -->      <property name="securityManager" ref="securityManager" />      <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->      <property name="loginUrl" value="/login.do" />      <!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->      <property name="successUrl" value="/first.do" />      <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面 -->      <property name="unauthorizedUrl" value="/refuse.jsp" />        <!-- 自定义filter配置 -->      <property name="filters">          <map>              <!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中 -->              <entry key="authc" value-ref="formAuthenticationFilter" />          </map>      </property>        <!-- Shiro连接约束配置,即过滤链的定义 -->      <property name="filterChainDefinitions">          <value>              <!-- /** = anon所有url都可以匿名访问 -->              <!-- 对静态资源设置匿名访问 -->              /images/** = anon              /js/** = anon              /styles/** = anon              <!-- 验证码,可匿名访问 -->              /validatecode.jsp = anon                <!-- 请求 logout.action地址,shiro去清除session -->              /logout.action = logout              <!--商品查询需要商品查询权限 ,取消url拦截配置,使用注解授权方式 -->              <!-- /items/queryItems.action = perms[item:query] -->              <!-- 配置记住我或认证通过可以访问的地址 -->              /** = user              <!-- /** = authc 所有url都必须认证通过才可以访问 -->              /**=authc            </value>      </property>  </bean>    <!-- 自定义form认证过虑器 -->  <!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->  <bean id="formAuthenticationFilter" class="cn.me.ssm.shiro.CustomFormAuthenticationFilter ">      <!-- 表单中账号的input名称 -->      <property name="usernameParam" value="username" />      <!-- 表单中密码的input名称 -->      <property name="passwordParam" value="password" />      <!-- 记住我input的名称 -->      <property name="rememberMeParam" value="rememberMe"/>  </bean>    <!-- 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>    <!-- 安全管理器 -->  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">      <!-- 注入自定义Realm -->      <property name="realm" ref="customRealm" />      <!-- 注入缓存管理器 -->      <property name="cacheManager" ref="cacheManager" />      <!-- 注入session管理器 -->      <property name="sessionManager" ref="sessionManager" />      <!-- 记住我 -->      <property name="rememberMeManager" ref="rememberMeManager"/>  </bean>  登陆页面[html] view plain copy<tr>                              <TD></TD>                              <td><input type="checkbox" name="rememberMe" />自动登陆</td>                          </tr>  

阅读全文
0 0
原创粉丝点击