【Java】SpringMVC项目利用Shiro设置固定时间内密码登录重试次数限制

来源:互联网 发布:usleep函数 linux 编辑:程序博客网 时间:2024/05/19 14:20

1.pom配置:

<!-- shiro --><dependency>    <groupId>commons-logging</groupId>    <artifactId>commons-logging</artifactId>    <version>1.1.3</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-core</artifactId>    <version>1.4.0</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-web</artifactId>    <version>1.4.0</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-ehcache</artifactId>    <version>1.4.0</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-spring</artifactId>    <version>1.4.0</version></dependency> <!-- shiro end -->
  1. ecache.xml
<?xml version="1.0" encoding="UTF-8"?><ehcache name="shirocache">    <diskStore path="java.io.tmpdir"/>        <!-- 登录记录缓存 锁定10分钟 -->    <cache name="passwordRetryCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="3600"           timeToLiveSeconds="0"           overflowToDisk="false"           statistics="true">    </cache>   </ehcache>

3.application-spring-shiro.xml配置

<?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:p="http://www.springframework.org/schema/p"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsdhttp://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache-4.0.xsd">    <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->      <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">           <!-- 调用我们配置的权限管理器 -->        <property name="securityManager" ref="securityManager"/>           <!-- 配置我们的登录请求地址 -->           <property name="loginUrl" value="/"/>        <!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 -->        <!-- <property name="successUrl" value="/"/> -->        <!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 -->        <property name="unauthorizedUrl" value="/pages/error403.jsp"/>        <!-- 权限配置 -->        <property name="filterChainDefinitions">            <value>                <!-- anon表示此地址不需要任何权限即可访问 -->                  <!-- perms[user:query]表示访问此连接需要权限为user:query的用户 -->                  <!-- roles[manager]表示访问此连接需要用户的角色为manager -->                  /static/**=anon                /about/*=anon                 /logins/*=anon                 /pages/error403.jsp=anon                 /pages/login.jsp=anon                 /pages/index.jsp=anon                                 /pages/menu/menulist.jsp=perms[user:view]                                <!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/-->                /** = authc              </value>            </property>        </bean>        <!-- 缓存管理器 使用Ehcache实现 -->    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">        <property name="cacheManagerConfigFile" value="classpath:ehcache/ehcache.xml"/>    </bean>        <!-- 安全管理器 -->    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">            <!-- ref对应我们写的realm  MyShiro -->          <property name="realms" >        <list><ref bean="SimpleRealm"/></list>        </property>        <!-- 使用下面配置的缓存管理器 -->          <property name="cacheManager" ref="cacheManager"/>    </bean>            <!-- 配置进行授权和认证的 Realm -->      <bean id="SimpleRealm" class="com.naton.shiro.SimpleRealm"         init-method="initCredentialsMatcher">           <property name="cacheManager" ref="cacheManager"/>    </bean>          <!-- 配置 Bean 后置处理器: 会自动的调用和 Spring 整合后各个组件的生命周期方法. -->    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />    <!-- Support Shiro Annotation -->    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">    <property name="proxyTargetClass" value="true" />    </bean>    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">        <property name="securityManager" ref="securityManager"/>    </bean></beans>

4.关键地方的代码编写:

package com.naton.shiro;import javax.annotation.PostConstruct;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.session.Session;import org.apache.shiro.subject.PrincipalCollection;import com.naton.pojo.po.UserInfo;import org.apache.shiro.cache.CacheManager;public class SimpleRealm extends AuthorizingRealm {private CacheManager cacheManager;public CacheManager getCacheManager() {return cacheManager;}public void setCacheManager(CacheManager cacheManager) {this.cacheManager = cacheManager;}/** * 初始化密码部分验证条件 */    public void initCredentialsMatcher() {//该句作用是重写shiro的密码验证,让shiro用自定义的验证      CustomCredentialsMatcher customCredentialsMatcher = new CustomCredentialsMatcher(cacheManager);        setCredentialsMatcher(customCredentialsMatcher);      }/** * 认证  */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {CustomToken token = (CustomToken) authenticationToken;                    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(  token.getPrincipal(), //用户名  token.getCredentials(), //密码                  getName()  //realm name          );return authenticationInfo;}/** * 授权 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();Session session = SecurityUtils.getSubject().getSession();UserInfo user = (UserInfo) session.getAttribute("currentUser");if (user != null) {//通过用户名从数据库获取权限字符串authorizationInfo.setStringPermissions(user.getPermissions());}        return authorizationInfo;}}
package com.naton.shiro;import java.util.concurrent.atomic.AtomicInteger;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;import org.apache.shiro.cache.Cache;import com.naton.advice.exception.ServiceException;import org.apache.shiro.cache.CacheManager;/**  * 自定义 密码验证类  *  * @author q  *  */public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {  //private Ehcache passwordRetryCache;private Cache<String,AtomicInteger> passwordRetryCache;public CustomCredentialsMatcher(CacheManager cacheManager) { passwordRetryCache = cacheManager.getCache("passwordRetryCache");      }    @Override    public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {            UsernamePasswordToken token = (UsernamePasswordToken) authcToken;        String loginName = token.getUsername();String pwd = String.valueOf(token.getPassword());AtomicInteger retryCount = passwordRetryCache.get(loginName);if(retryCount==null){retryCount = new AtomicInteger();passwordRetryCache.put(loginName, retryCount);}if(retryCount.incrementAndGet()>5){     //throw new ExcessiveAttemptsException();throw new ServiceException(0,"输入错误次数已经达到5次");}//假设的一个验证机制        int resp;try {resp = Integer.parseInt(pwd);} catch (Exception e) {resp = 0;}if(resp == 1){//clear retry countpasswordRetryCache.remove(loginName);            return true;}else{return false;}    }public Cache<String, AtomicInteger> getPasswordRetryCache() {return passwordRetryCache;}public void setPasswordRetryCache(Cache<String, AtomicInteger> passwordRetryCache) {this.passwordRetryCache = passwordRetryCache;}    }
知行办公,专业移动办公平台 https://zx.naton.cn/
原创团队
【总监】十二春秋之,3483099@qq.com;
【Master】zelo,616701261@qq.com;【运营】运维艄公,897221533@qq.com;
【产品设计】流浪猫,364994559@qq.com;【体验设计】兜兜,2435632247@qq.com;
【iOS】淘码小工,492395860@qq.com;iMcG33K,imcg33k@gmail.com;
【Android】人猿居士,1059604515@qq.com;思路的顿悟,1217022114@qq.com;
【java】首席工程师MR_W,feixue300@qq.com;【测试开发】土镜问道,847071279@qq.com
【数据】fox009521,42151960@qq.com;【安全】保密,你懂的。
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 核桃木色 核桃木和橡木哪个好 胡桃木与核桃木的区别 核桃木 胡桃木 核桃木好吗 求购核桃木 收购核桃木 核桃木和胡桃木的区别 核桃木实木门 核桃木是胡桃木吗 核桃木家具价格及图片 黑胡桃木多少钱一立方 胡桃木与核桃木区别 实木家具好处 实木家具什么好 实木家具好吗 核桃木板材 核桃糕 红枣包核桃 红枣与核桃 核桃红枣粥 红枣核桃粥 红枣核桃露 核桃糕的做法 红枣夹核桃做法 红枣夹核桃哪个牌子好 红枣夹核桃的功效 核桃有什么作用 核桃红枣粥的功效 枣加核桃 枣包核桃 枣夹核桃哪个牌子好 枣夹核桃仁500g包邮 枣加核桃价格 枣夹核桃多少钱一斤 核桃夹心枣 枣夹核桃图片 枣夹核桃的营养价值 枣夹核桃功效 求核桃树苗 核桃苗厂家