同步操作将从 BYStudio/shiro-redis 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
Shiro集成Redis的适配器,为解决shiro-ehcache不利于集群而打造的集中式缓存方案。
Maven坐标
<dependency>
<groupId>org.iherus.shiro</groupId>
<artifactId>shiro-redis</artifactId>
<version>2.5.0</version>
</dependency>
SpringBoot:
<dependency>
<groupId>org.iherus.shiro</groupId>
<artifactId>shiro-redis-spring-boot-web-starter</artifactId>
<version>2.5.0</version>
</dependency>
v2.5.0:
Change Log
1)解决Issues:#I1YUFN、#I2BSCN、
#I2B7LC、#I22K17、#I26UHZ。
2)支持session永不失效,#I2BCKL 。
v2.4.0:【存在bug,请忽略此版本】
常规bug fix 版本
v2.3.0:
Change Log
1)解决RedisSessionDAO#uncache方法抛出StackOverflowError。Issues:#I1TIIG
2)依赖升级,其中Shiro的版本升至1.6.0。
v2.2.0:
Change Log
1)加入scope策略.
v2.1.0:
Change Log
1)修复bug.
2)增强兼容性
3)发布shiro-redis-spring-boot-web-starter
v2.0.0:
Note
此版本为重构版本,API不兼容v1.x。
Change Log
1)在v1.x仅支持单机模式的基础上,新增了对 哨兵(Sentinel)、集群(Cluster)模式的支持。
2)支持Lettuce客户端、Redisson客户端
3)兼容Spring-data-redis
4)非集群模式,可设置独立的database
5)支持设置缓存失效时间
6)优化性能
7)新增RedisSessionDAO用于降低请求Redis的频率
1、基于ini的使用方式
[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=MD5
#散列次数
credentialsMatcher.hashIterations=2
#定义缓存池配置
poolConfig=redis.clients.jedis.JedisPoolConfig
poolConfig.minIdle=3
poolConfig.maxIdle=10
poolConfig.maxWaitMillis=1500
poolConfig.maxTotal=100
#定义连接配置
## Standalone
configuration=org.iherus.shiro.cache.redis.config.RedisStandaloneConfiguration
configuration.host=127.0.0.1
configuration.port=6379
configuration.database=2
#configuration.password=
## Sentinel
#configuration=org.iherus.shiro.cache.redis.config.RedisSentinelConfiguration
#configuration.masterName=mymaster
#configuration.sentinelsFromText=127.0.0.1:56379,127.0.0.1:56479,127.0.0.1:56579
#configuration.database=2
#configuration.password=
## Cluster
#configuration=org.iherus.shiro.cache.redis.config.RedisClusterConfiguration
#configuration.clusterNodesFromText=127.0.0.1:16379, 127.0.0.1:16380, 127.0.0.1:16381, 127.0.0.1:16382, 127.0.0.1:16383, 127.0.0.1:16384
#configuration.password=
#定义连接工厂
## Jedis
connectionFactory=org.iherus.shiro.cache.redis.connection.jedis.JedisConnectionFactory
connectionFactory.poolConfig=$poolConfig
connectionFactory.configuration=$configuration
#connectionFactory.clientName=
#connectionFactory.connectTimeoutMillis=
#connectionFactory.soTimeoutMillis=
## Lettuce
#connectionFactory=org.iherus.shiro.cache.redis.connection.lettuce.LettuceConnectionFactory
#connectionFactory.poolConfig=$poolConfig
#connectionFactory.configuration=$configuration
#connectionFactory.clientName=
#connectionFactory.timeoutMillis=
## Redisson
#connectionFactory=org.iherus.shiro.cache.redis.connection.redisson.RedissonConnectionFactory
#connectionFactory.configuration=$configuration
#connectionFactory.clientName=
#connectionFactory.connectTimeoutMillis=
#connectionFactory.soTimeoutMillis=
#定义缓存管理器
cacheManager=org.iherus.shiro.cache.redis.RedisCacheManager
cacheManager.connectionFactory=$connectionFactory
cacheManager.expirationMillis=900000
cacheManager.keyPrefix=shiro:test:cache:
#cacheManager.scanBatchSize=3000
#cacheManager.deleteBatchSize=5000
#cacheManager.fetchBatchSize=50
#cacheManager.database=5
#将凭证匹配器设置到realm
customRealm=org.iherus.shiro.tester.CustomRealm
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm
securityManager.cacheManager=$cacheManager
详细测试代码请看:src/test/java/org/iherus/shiro /tester/SimpleCacheTest.java
2、Spring集成的方式
<!-- SHIRO安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm" />
<property name="cacheManager" ref="cacheManager" />
<property name="rememberMeManager" ref="rememberMeManager" />
<property name="sessionManager" ref="sessionManager" />
</bean>
<!-- 用户域 -->
<bean id="userRealm" class="org.iherus.shiro.tester.CustomRealm" />
<!-- 会话管理器-->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO" />
<property name="globalSessionTimeout" value="${shiro.globalSessionTimeout}" />
<property name="deleteInvalidSessions" value="${shiro.deleteInvalidSessions}" />
<property name="sessionValidationInterval" value="${shiro.sessionValidationInterval}" />
</bean>
<!-- sessionDAO-->
<bean id="sessionDAO" class=" org.iherus.shiro.cache.redis.RedisSessionDAO">
<property name="cacheManager" ref="cacheManager" />
</bean>
<!-- 记住登录管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie" ref="rememberMeCookie" />
</bean>
<!-- Cookie对象 -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<property name="name" value="${shiro.cookieName}" />
<property name="maxAge" value="${shiro.cookieMaxAge}" />
</bean>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.iherus.shiro.cache.redis.RedisCacheManager">
<property name="connectionFactory" ref="connectionFactory" />
<property name="database" value="2" />
<property name="expirationMillis" value="90000" />
<property name="keyPrefix" value="shiro:cache:" />
<property name="scanBatchSize" value="3000" />
<property name="deleteBatchSize" value="5000" />
<property name="fetchBatchSize" value="50" />
</bean>
<!-- Redis连接工厂 -->
<bean id="connectionFactory" class="org.iherus.shiro.cache.redis.connection.jedis.JedisConnectionFactory">
<property name="clientName" value="SRC" />
<property name="connectTimeoutMillis" value="3000" />
<property name="soTimeoutMillis" value="2000" />
<property name="poolConfig" ref="poolConfig" />
<property name="configuration" ref="standaloneConfiguration" />
<!-- <property name="configuration" ref="sentinelConfiguration" /> -->
<!-- <property name="configuration" ref="clusterConfiguration" /> -->
</bean>
<!-- Redis单机配置 -->
<bean id="standaloneConfiguration" class="org.iherus.shiro.cache.redis.config.RedisStandaloneConfiguration">
<property name="host" value="127.0.0.1" />
<property name="port" value="6379" />
<property name="database" value="0" />
<!-- <property name="password" value="" /> -->
</bean>
<!-- Redis哨兵配置 -->
<bean id="sentinelConfiguration" class="org.iherus.shiro.cache.redis.config.RedisSentinelConfiguration">
<property name="masterName" value="mymaster" />
<property name="sentinelsFromText" value="127.0.0.1:56379,127.0.0.1:56479,127.0.0.1:56579" />
<!-- <property name="password" value="" /> -->
</bean>
<!-- Redis集群配置 -->
<bean id="clusterConfiguration" class="org.iherus.shiro.cache.redis.config.RedisClusterConfiguration">
<property name="clusterNodesFromText" value="127.0.0.1:16379,127.0.0.1:16380,127.0.0.1:16381..." />
<property name="maxAttempts" value="5" />
<!-- <property name="password" value="" /> -->
</bean>
<!-- 配置缓存连接池 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="minIdle" value="${redis.minIdle}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<property name="maxTotal" value="${redis.maxTotal}" />
</bean>
3、Spring Boot集成的方式
3-1)引入Spring Boot Starter依赖项:
<dependency>
<groupId>org.iherus.shiro</groupId>
<artifactId>shiro-redis-spring-boot-web-starter</artifactId>
<version>{latestVersion}</version>
</dependency>
$\color{red}{注意:由于客户端工具是可选依赖,所以,请根据需要引入相应依赖,支持jedis、lettuce、redisson和spring-data-redis,}$
$\color{red}{如若使用lettuce,还需要再引入commons-pool2。}$
3-2)默认情况下,shiro-redis-spring-boot-web-starter会自动创建 RedisCacheManager 和 RedisSessionDAO 实例并注入 WebSecurityManager 和 WebSessionManager中,如果您需要自定义 SecurityManager 和 SessionManager。
示例如下:
@Bean
public SessionManager sessionManager(SessionDAO sessionDAO) {
DefaultWebSessionManager webSessionManager = new DefaultWebSessionManager();
// 注入RedisSessionDAO实例
webSessionManager.setSessionDAO(sessionDAO);
.....other.....
return webSessionManager;
}
@Bean
public DefaultWebSecurityManager securityManager(SessionManager sessionManager, CacheManager cacheManager, List<Realm> realms) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 注入SessionManager实例
securityManager.setSessionManager(sessionManager);
// 注入cacheManager实例
securityManager.setCacheManager(cacheManager != null ? cacheManager : new MemoryConstrainedCacheManager());
securityManager.setRealms(realms);
.....other.....
return securityManager;
}
3-3)SSL相关配置,提供了接口:JedisSslClientConfigurationCustomizer、LettuceClientConfigurationCustomizer、RedissonSslClientConfigurationCustomizer,可根据需要去实现定制器,并注册Bean。
示例如下:
@Bean
public JedisSslClientConfigurationCustomizer JedisSslClientConfigurationCustomizer() {
return ((builder) -> {
....SSL配置....
});
}
3-4)配置属性
属性项 | 缺省 | 描述 |
---|---|---|
基本配置 | ||
shiro.redis.host | localhost | 主机名 |
shiro.redis.port | 6379 | 端口 |
shiro.redis.database | 0 | 数据库 |
shiro.redis.password | 密码 | |
shiro.redis.sentinel.master-name | 哨兵模式中主节点名称 | |
shiro.redis.sentinel.nodes | 哨兵节点地址串,逗号分隔,eg:127.0.0.1:56379,127.0.0.1:56479,127.0.0.1:56579 | |
shiro.redis.cluster.max-attempts | 5 | 最大重试次数 |
shiro.redis.cluster.nodes | 集群节点地址串,逗号分隔,eg: 127.0.0.1:16379,127.0.0.1:16380,127.0.0.1:16381... | |
Jedis | ||
shiro.redis.jedis.client-name | 客户端名称 | |
shiro.redis.jedis.connect-timeout | 2000ms | 连接超时 |
shiro.redis.jedis.so-timeout | 2000ms | 读取超时 |
shiro.redis.jedis.ssl | false | 是否启用SSL |
shiro.redis.jedis.pool.min-idle | 3 | |
shiro.redis.jedis.pool.max-idle | 8 | |
shiro.redis.jedis.pool.max-total | 8 | |
shiro.redis.jedis.pool.max-wait-millis | 90000 | |
shiro.redis.jedis.pool.min-evictable-idle-time-millis | 60000 | |
shiro.redis.jedis.pool.test-on-borrow | false | |
shiro.redis.jedis.pool.test-while-idle | true | |
shiro.redis.jedis.pool.time-between-eviction-runs-millis | 30000 | |
shiro.redis.jedis.pool.num-tests-per-eviction-run | -1 | |
Lettuce | ||
shiro.redis.lettuce.client-name | 客户端名称 | |
shiro.redis.lettuce.read-from | 读操作节点偏好 | |
shiro.redis.lettuce.ssl | false | 是否启用SSL |
shiro.redis.lettuce.verify-peer | true | 是否启用SSL证书校验 |
shiro.redis.lettuce.start-tls | false | 是否启用StartTLS |
shiro.redis.lettuce.pool.min-idle | 3 | |
shiro.redis.lettuce.pool.max-idle | 8 | |
shiro.redis.lettuce.pool.max-total | 8 | |
shiro.redis.lettuce.pool.max-wait-millis | 90000 | |
shiro.redis.lettuce.pool.min-evictable-idle-time-millis | 60000 | |
shiro.redis.lettuce.pool.test-on-borrow | false | |
shiro.redis.lettuce.pool.test-while-idle | true | |
shiro.redis.lettuce.pool.time-between-eviction-runs-millis | 30000 | |
shiro.redis.lettuce.pool.num-tests-per-eviction-run | -1 | |
Redisson | ||
shiro.redis.redisson.client-name | 客户端名称 | |
shiro.redis.redisson.connect-timeout | 10000ms | 连接超时 |
shiro.redis.redisson.connection-min-idle-size | 8 | 最少空闲连接数 |
shiro.redis.redisson.connection-pool-size | 32 | 连接池大小 |
shiro.redis.redisson.so-timeout | 3000ms | 读取超时 |
shiro.redis.redisson.ssl | false | 是否启用SSL |
Shiro缓存配置 | ||
shiro.redis.cache.batch-options.delete-batch-size | 5000 | 批量删除数量 |
shiro.redis.cache.batch-options.fetch-batch-size | 50 | 批量获取数量 |
shiro.redis.cache.batch-options.scan-batch-size | 3000 | 每批次扫描数量 |
shiro.redis.cache.database | 0 | shiro缓存数据库 |
shiro.redis.cache.expiration | PT15M | shiro缓存失效时长 |
shiro.redis.cache.key-prefix | shiro:cache: | shiro缓存键前缀 |
4、关于缓存key的特别说明
针对非 byte[] 和 String 类型的缓存key,采用的是生成MD5作为key的策略,这样就要求AuthorizingRealm#doGetAuthenticationInfo返回的[PrincipalCollection principals]必须是一成不变的,这样一来,如果后续需要动态修改principals的属性,则会导致缓存key的变化。
所以,建议重写这两个方法来应对这种变化:
1)AuthorizingRealm #getAuthorizationCacheKey(PrincipalCollection principals)
2)AuthorizingRealm #getAuthenticationCacheKey(PrincipalCollection principals)
eg:
/**
* 建议重写此方法,提供唯一的缓存Key
*/
@Override
protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
return this.getAuthenticationCacheKey(principals);
}
/**
* 建议重写此方法,提供唯一的缓存Key
*/
@SuppressWarnings("unchecked")
@Override
protected Object getAuthenticationCacheKey(PrincipalCollection principals) {
StringBuilder sb = new StringBuilder();
principals.forEach(principal -> {
sb.append(((User) principal).getId());
});
return sb.toString();
}
更多正在补充中。。。。。
Features
欢迎提出更好的意见,帮助完善 shiro-redis
Copyright
Apache License, Version 2.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。