shiro中session实现的简单分析

本文详细分析了Shiro框架在处理Session时的内部流程,从web.xml配置到DelegatingFilterProxy,再到AbstractShiroFilter的doFilterInternal方法,深入探讨了Subject的创建、Session的获取和管理,包括如何通过SessionKey获取sessionId,以及如何从数据源中检索Session。通过这次分析,有助于更好地理解Shiro的Session机制。
摘要由CSDN通过智能技术生成

前阵子对shiro进行分布式环境下的改造时跟了一遍源码,当时只是使用了思维带图简要的记录了一下方法的调用过程。最近有空了决定用博客详细的记录分析一下这个流程,以帮助自己更好的理解。

###配置
首先看看shiro在web.xml文件中的配置

 <!-- shiro过滤器 -->
 <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 </filter>
 
 <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

可以看到使用的<filter-class>标签是Spring的代理过滤器,那么它是如何代理shiro的过滤器的呢?看看DelegatingFilterProxy的源码

	@Override
	protected void initFilterBean() throws ServletException {
		synchronized (this.delegateMonitor) {
			if (this.delegate == null) {
				// If no target bean name specified, use filter name.
				//如果没有delegate则根据<filter-name>去Spring容器中寻找对应的bean
				if (this.targetBeanName == null) {
					this.targetBeanName = getFilterName();
				}
				// Fetch Spring root application context and initialize the delegate early,
				// if possible. If the root application context will be started after this
				// filter proxy, we'll have to resort to lazy initialization.
				WebApplicationContext wac = findWebApplicationContext();
				if (wac != null) {
					this.delegate = initDelegate(wac);
				}
			}
		}
	}

于是Spring中应该配置了name为shiroFilter的bean,下面看看Spring中与shiro相关的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

     <!-- shiroFilter对象 -->
     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
     	<property name="securityManager" ref="securityManager"/>
		<property name="loginUrl" value="/user/loginpage"/>
		<property name="unauthorizedUrl" value="/403.html"/>
		<property name="filterChainDefinitions">
		     <value>
		         /user/loginpage = anon
		         /user/login = anon
		         /* = authc
		         /user/perms1 = perms["user:delete"]
		         /user/perms2 = perms["user:select"]
		         /user/admin = roles["admin"]
		         #自定义的过滤器,只要多个权限中有一个满足即可
		         /user/users = rolesOr["admin","user"]
		     </value>
		 </property>
		 
		 <property name="filters">
		     <map>
		       <entry key="rolesOr" value-ref="rolesOrFilter" />
		     </map>
		 </property>
     </bean>
     
     <!-- 创建securityManager -->
     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
         <property name="realm" ref="realm"></property>
         <property name="sessionManager" ref="sessionManager"></property>
     </bean>
     
     <!-- 创建realm -->
     <bean id="realm" class="com.cfh.studyshiro.common.CustomeRealm">
     </bean>
     
     <!-- 自定义过滤器 -->
     <bean id="rolesOrFilter" class="com.cfh.studyshiro.filter.RolesOrFilter" />
     
     <!-- 注入自定义的sessionDao -->
     <bean id="redisSessionDao" class="com.cfh.studyshiro.common.RedisSessionDao" />
     
     <!-- 在sessionManager中引入自定义的sessionDao -->
     <bean id="sessionManager" class="com.cfh.studyshiro.common.CustomSessionManager">
        <property name="sessionDAO" ref="redisSessionDao" />
        <!-- 关闭cookie -->
        <!-- <property name="sessionIdCookieEnabled" value="false" /> -->
     </bean>
</beans>

ShiroFilterFactoryBean的源码这里不进行讨论,先看看ShiroFilterFactoryBean.class中生成ShiroFilter的createInstance()方法

protected AbstractShiroFilter createInstance() throws Exception {

        log.debug("Creating Shiro Filter instance.");

        SecurityManager securityManager = getSecurityManager();
        if (securityManager == null) {
            String msg = "SecurityManager property must be set.";
            throw new BeanInitializationException(msg);
        }

        if (!(securityManager instanceof WebSecurityManager)) {
            String msg = "The security manager does not implement the WebSecurityManager interface.";
            throw new BeanInitializationException(msg);
        }

        FilterChainManager manager
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值