基于shiro+redis缓存的session共享方案

松烨烨
2023-12-01

基于shiro+redis缓存的session共享方案

当一个使用shiro开发的项目被定位为单机部署,不需要集群部署时,我们可以不考虑shiro redis集群;然而很多大型项目是需要集群部署的,以应对高并发访问量。

由 redis负责 session 数据的存储和授权信息cache共享,而我们自己实现的 session manager 将负责 session 生命周期的管理。结构示例如下图

特征:

  • 可以使用redis管理shiro session
  • 解决集群中session同步的问题
  • 解决集群中缓存应用的问题
  • 多个不同子域名很容易实现统一登陆

此方案的不足之处:

  • 不同的域名(非子域名)做session共享,只能通过单点登录。
  • redis单点故障,可能需要集群式部署

·项目配置几处关键点:

·web.xml主要配置示例

·

·

·

·shiroFilter

·

·org.springframework.web.filter.DelegatingFilterProxy

·

·targetFilterLifecycle

·true

·

·

·

·shiroFilter

·/*

·REQUEST

·FORWARD

·INCLUDE

·ERROR

·

·

spring-shiro.xml主要配置示例

<beanid=“shiroFilter” class=“org.apache.shiro.spring.web.ShiroFilterFactoryBean”>

<propertyname=“securityManager” ref=“securityManager”/>

<propertyname=“loginUrl” value=“/login”/>

<propertyname=“successUrl” value=“/index”/>

<propertyname=“unauthorizedUrl” value=“/unauthorized”/>

<propertyname=“filterChainDefinitions”>

/js/**= anon

/index.htm*=anon

/unauthorized.jsp*=anon

/login.jsp*= anon

/login.do = authc

/logout.do = authc

/**= authc

<beanid=“securityManager” class=“org.apache.shiro.web.mgt.DefaultWebSecurityManager”>

<propertyname=“realm” ref=“redisRealm”/>

<propertyname=“sessionManager” ref=“sessionManager”/>

<propertyname=“cacheManager” ref=“cacheManager”/>

<beanid=“lifecycleBeanPostProcessor” class=“org.apache.shiro.spring.LifecycleBeanPostProcessor”/>

<beanclass=“org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator”

depends-on=“lifecycleBeanPostProcessor”/>

<beanclass=“org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor”>

<propertyname=“securityManager” ref=“securityManager”/>

<beanid=“redisSessionDAO” class=“com.xxxx.webkits.shiro.RedisSessionDAO”>

<propertyname=“expire” value=“3600”/>

<beanid=“sessionManager” class=“org.apache.shiro.web.session.mgt.DefaultWebSessionManager”>

<propertyname=“sessionDAO” ref=“redisSessionDAO”/>

<propertyname=“sessionIdCookie” ref=“sessionIdCookie”/>

<beanid=“cacheManager” class=“com.xxxxx.webkits.shiro.RedisCacheManager”>

<propertyname=“expire” value=“3600”/>

<beanid=“sessionIdCookie” class=“org.apache.shiro.web.servlet.SimpleCookie”>

<constructor-argvalue=“sid”/>

<propertyname=“httpOnly” value=“true”/>

<propertyname=“domain” value=“vip.xkeshi.com”/>

项目中要是自定义一个Realm类,继承AuthorizingRealm抽象类,重载doGetAuthenticationInfo()与doGetAuthorizationInfo() 实现获取用户信息及授权信息查询

/**

*Created by ylc on 2016/2/1.

*/

@Component(“redisRealm”)

public class RedisRealm extends AuthorizingRealm {

private RedisManager redisManager;

//权限验证-授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用

@Override

protected AuthorizationInfodoGetAuthorizationInfo(PrincipalCollection principalCollection) {…}

//登陆验证-认证回调函数,登录时调用

@Override

protected AuthenticationInfodoGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {…}

另外:

项目中需要配置 redis 连接池~ 否则无法使用

项目依赖示例,仅供参考

com.xxxxx

xxxx-framework-webkits

1.0.8-SNAPSHOT

com.xxxx

xxxx-framework-core

1.0.8-SNAPSHOT

org.apache.shiro

shiro-core

1.2.3

org.apache.shiro

shiro-web

1.2.3

org.apache.shiro

shiro-spring

1.2.3

 类似资料: