超简单Shiro会话管理和加密


一、缓存

1.添加依赖

<dependency>
			<groupId>org.crazycake</groupId>
			<artifactId>shiro-redis</artifactId>
			<version>3.1.0</version>
		</dependency>

2.配置文件

#Redis服务器地址
spring.redis.host=localhost
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码
#spring.redis.password=foobared
#连接池最大连接数
spring.redis.lettuce.pool.max-active=8
#连接池最大阻塞等待时间
spring.redis.lettuce.pool.max-wait=-1
#连接池最大空闲连接
spring.redis.lettuce.pool.max-idle=8
#连接池最小空闲连接
spring.redis.lettuce.pool.min-idle=0
#Redis服务器超时时间
spring.redis.timeout=5000

3.改造ShiroConfig

 @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

@Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm shiroRealm = new MyShiroRealm();
        //设置启用缓存
        shiroRealm.setCachingEnabled(true);
        shiroRealm.setAuthorizationCachingEnabled(true);
        shiroRealm.setAuthorizationCacheName("authorizationCache");
        //设置凭证
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }

  @Bean
    public SecurityManager securityManager(){
        //安全管理器
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //注入Realm
        securityManager.setRealm(myShiroRealm());
        //注入缓存管理器
        securityManager.setCacheManager(cacheManager());
        //注入会话管理器
        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        //Shiro过滤器
        ShiroFilterFactoryBean shiroFilterFactory = new ShiroFilterFactoryBean();
        //注入SecurityManager
        shiroFilterFactory.setSecurityManager(securityManager);
        //权限验证:使用Filter控制资源(URL)的访问
        shiroFilterFactory.setLoginUrl("/dologin");
        shiroFilterFactory.setSuccessUrl("/main");
        shiroFilterFactory.setUnauthorizedUrl("/403");//没有权限跳转


        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();

        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/fonts/**","anon");
        filterChainDefinitionMap.put("/images/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/localcss/**","anon");
        filterChainDefinitionMap.put("/localjs/**","anon");

        filterChainDefinitionMap.put("/login","anon");
        filterChainDefinitionMap.put("/logout","logout");//注销过滤器

        //配置需要特定权限才能访问的资源
//        filterChainDefinitionMap.put("/user/list","perms[用户列表]");
//        filterChainDefinitionMap.put("/user/add","perms[用户添加]");
//        filterChainDefinitionMap.put("/user/edit","perms[用户编辑]");
//        filterChainDefinitionMap.put("/user/del","perms[用户删除]");

        //动态授权
        List<SysRight> rights = roleService.findAllRights();
        for (SysRight right :rights){
            if (right.getRightUrl()!=null && !right.getRightUrl().trim().equals("")){
                filterChainDefinitionMap.put(right.getRightUrl(),"perms["+right.getRightCode()+"]");
            }
        }


        //配置认证访问
        filterChainDefinitionMap.put("/**","authc");//必须放在过滤器的最后面

        shiroFilterFactory.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactory;
    }

4.测试
它会报User转换错误别慌! 添加一个热部署包来提高效率先!!!

在这里插入图片描述
完成后再Redis中查看信息如下:
在这里插入图片描述

二、加密

1.测试

加上"盐"试试

    @Test
    public void testMd5Hash(){
        String password = "admin";
        String salt = "czkt";
        Md5Hash md5Hash = new Md5Hash(password,salt,1);
        System.out.println(md5Hash.toString());
        //输出36aa3e095a86925b7658b5d00557fa77
    }

2.加密和验证

设俩个接口:

public interface PasswordService {
    String encryptPassword(Object plaintextPassword) throws IllegalArgumentException;
}
public interface CredentialsMatcher {
    boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);
}

3.具体实现

1.在Service添加加密方法:

@Override
    public String encryptPassword(Object plaintextPassword) throws IllegalArgumentException {
        Md5Hash md5Hash = new Md5Hash(plaintextPassword,"",1);
        String mdPass=md5Hash.toString();
        Md5Hash md5 = new Md5Hash(plaintextPassword,mdPass.toString(),2);
        return md5Hash.toString();
    }

2.在ShiroConfig中注入MyShiroRealm

@Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    //使用md5算法进行加密
    hashedCredentialsMatcher.setHashAlgorithmName("md5");
    //设置散列次数
        hashedCredentialsMatcher.setHashIterations(1);
        return hashedCredentialsMatcher;

    }

3.修改返回身份信息的代码

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("调用MyShiroRealm.doGetAuthenticaticationInfo 获取身份信息!");
        //获取身份信息
        UsernamePasswordToken token =(UsernamePasswordToken)authenticationToken;
        String usrName = token.getUsername();

        //每次访问,登录次数加1
        ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();

        operations.increment(SHIRO_LOGIN_COUNT+usrName,1);

        //计数大于5时设置用户被锁定一小时,清空登录计数
        if (Integer.parseInt(operations.get(SHIRO_LOGIN_COUNT+usrName))>5){
            operations.set(SHIRO_IS_LOCK+usrName,"LOCK");
            stringRedisTemplate.expire(SHIRO_IS_LOCK+usrName,1, TimeUnit.HOURS);

            stringRedisTemplate.delete(SHIRO_LOGIN_COUNT+usrName);//清空登录计数
        }

        if ("LOCK".equals(operations.get(SHIRO_IS_LOCK+usrName))){
            throw new DisabledAccountException();
        }

        User user = userService.getUserByUserName(usrName);

        if (user==null){
            throw new UnknownAccountException();//账号错误

        }
        if (user.getUsrFlag()==null || user.getUsrFlag().intValue()==0){
            throw new LockedAccountException();//账号锁定
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getUsrPassword(), ByteSource.Util.bytes("czkt"),getName());

        return info;

    }

**这样我们在去测试看看就好了!我们下次见~**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值