用redis作为shiro的登陆密码次数记录

上篇中,因为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中,设置相应的签名。

测试通过。

posted @ 2021-02-22 13:36  琴声清幽  阅读(81)  评论(0编辑  收藏  举报