上篇中,因为ehcache的单例原因,这里提供了另外一种方法。
用redis作为 shiro的密码凭证器的记载体。
package cn.taotao.shiro.service; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Singleton; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.ExcessiveAttemptsException; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheManager; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.io.ResourceUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.Cache.ValueWrapper; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.cache.RedisCache; import org.springframework.stereotype.Service; import com.hazelcast.internal.serialization.SerializableByConvention; import redis.clients.jedis.Jedis; @Service public class MyHashedCredentialsMatcher extends HashedCredentialsMatcher { private Integer retryCount = 0; @Autowired private Jedis jedis; public MyHashedCredentialsMatcher(Jedis jedis) { } @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { System.out.println("docredentialsmatch......"); String username = (String) token.getPrincipal(); System.out.println("username is issssss" + username); if (jedis.get(username) == null) { jedis.set(username, "0"); } retryCount = Integer.parseInt(jedis.get(username)) + 1; System.out.println("retryCount is : =============" + retryCount); jedis.set(username,retryCount.toString()); jedis.expire(username, 600); if (retryCount > 5) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); Date date = new Date(System.currentTimeMillis()); System.out.println("登录时间 " + formatter.format(date)); // if retry count > 5 throw jedis.expire(username, 2000); System.out.println("username: " + username + " tried to login more than 5 times in period"); throw new ExcessiveAttemptsException( "username: " + username + " tried to login more than 5 times in period"); } boolean matches = super.doCredentialsMatch(token, info); if (matches) { // clear retry count jedis.del(username); } return matches; } }
然后在shiro的config中,设置相应的签名。
测试通过。