您的位置:首页 > 编程语言 > Java开发

【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;【安全】保密,你懂的。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐