【Java】SpringMVC项目利用Shiro设置固定时间内密码登录重试次数限制
2017-12-26 14:04
615 查看
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 -->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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/cache http://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); } /** * 认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { CustomToken token = (CustomToken) authenticationToken; SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( token.getPrincipal(), //用户名 token.getCredentials(), //密码 getName() //realm name ); return authenticationInfo; } /** * 授权 */ @Override protected 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 count passwordRetryCache.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;【安全】保密,你懂的。
相关文章推荐
- win7利用组策略设置电脑开机登录密码次数限制技巧图解
- SpringBoot+Shiro学习之密码加密和登录失败次数限制
- 在设置iis windows身份验证,出错:登录失败:用户帐户限制。可能的原因包括不允许空密码登录时间限制或强制的策略限制。
- SpringBoot+Shiro学习之密码加密和登录失败次数限制
- SpringBoot+Shiro学习之密码加密和登录失败次数限制
- SpringBoot+Shiro学习之密码加密和登录失败次数限制示例
- 利用IP地址限制单位时间内投票次数
- 修改红旗Linux,Windows菜单时间,删除Linux登录密码,设置Linux自动登录
- 登录失败:用户帐户限制。可能的原因包括不允许空密码登录时间限制或强制的策略限制。
- Windows系统设置开机密码登录尝试失败次数的教程
- 用java模拟curl利用cookie登录抓取一个受密码保护的新页面 ( by quqi99 )
- Linux下设置限制登录oracle数据库及Linux操作系统的IP、尝试登录次数及长时间空闲后断开
- PHPCMS V9“密码重试次数太多,请过-xxx分钟后重新登录!”的解决办法
- 利用 tomcat 设置项目 密码登陆
- 局域共享解决——用户账户限制,可能的原因包括不允许空密码,登录时间限制
- Php中设置Session超时时间登录时间限制
- 登录的次数及时间限制
- Shiro security限制登录尝试次数
- 密码策略重试次数与锁定持续时间
- java项目同一浏览器下限制用户重复登录