Spring security 和 Spring session 一起使用

Spring security 中包含对Session的处理,在引入Spring session后,
两者是如何共存的。
有几个问题需要考虑:
1、两者Session存放的位置
2、Session的生命周期管理

第一个问题还没了解清楚,我暂时将问题记录下了,如果有高手知道可以私信我。
疑问如下:
在xml中security配置(session部分)如下:

<security:http>
<security:session-management invalid-session-url="/login.html?error=1" session-authentication-strategy-ref="sas" />
</security:http>
<bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
                <constructor-arg ref="sessionRegistry"/>
            </bean>
            <bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/>
            <bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
                <constructor-arg ref="sessionRegistry"/>
            </bean>
        </list>
    </constructor-arg>
</bean>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />

其中SessionRegistryImpl的部分代码:

/** <principal:Object,SessionIdSet> */
private final ConcurrentMap<Object, Set<String>> principals = new ConcurrentHashMap<Object, Set<String>>();
/** <sessionId:Object,SessionInformation> */
private final Map<String, SessionInformation> sessionIds = new ConcurrentHashMap<String, SessionInformation>();

明显是将一些user的信息存放在内存中的。
那么SpringSession是将Session信息放到Redis中的,两者矛盾,怎样做才能将SessionRegistryImpl中的信息存放到Redis中?
我能想到的是自己重写这部分,将principals、sessionIds信息写到Redis中。

第二个问题:Session生命周期
在Spring security中通过ApplicationEvent管理生命周期的,而SpringSession在session超时或者被删除时会发送ApplicationEvent。通过代码来看看:
首先在xml中会有如下配置:

 <context:annotation-config/>
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="300"/>
    </bean>

在RedisHttpSessionConfiguration的构造函数中:

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(
            RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(redisSessionMessageListener(),
                Arrays.asList(new PatternTopic("__keyevent@*:del"),new PatternTopic("__keyevent@*:expired")));
        return container;
    }

其中redisSessionMessageListener的类集成了MessageListener接口,熟悉redis的知道,这个接口时redis中的mq的监听接口,也就是说spring session在察觉Session过期或者被删除了的话,会广播一个消息,redisSessionMessageListener就会接受到这个消息,处理这个消息的函数如下:

public void onMessage(Message message, byte[] pattern) {
        byte[] messageChannel = message.getChannel();
        byte[] messageBody = message.getBody();
        if(messageChannel == null || messageBody == null) {
            return;
        }
        String channel = new String(messageChannel);
        if(!(channel.endsWith(":del") || channel.endsWith(":expired"))) {
            return;
        }
        String body = new String(messageBody);
        if(!body.startsWith("spring:session:sessions:")) {
            return;
        }

        int beginIndex = body.lastIndexOf(":") + 1;
        int endIndex = body.length();
        String sessionId = body.substring(beginIndex, endIndex);

        if(logger.isDebugEnabled()) {
            logger.debug("Publishing SessionDestroyedEvent for session " + sessionId);
        }

        publishEvent(new SessionDestroyedEvent(this, sessionId));
    }

上面最后一句就是发送一个SessionDestroyedEvent,这个Event就是ApplicationEvent。再通过如下配置Spring Security就能接收到这个消息了。

1、Spring security可以在通过配置设定超时返回的页面。

<security:session-management invalid-session-url="/login.html?error=1" session-authentication-strategy-ref="sas" />

2、在web.xml中配置

<listener> <listener-class> org.springframework.security.web.session.HttpSessionEventPublisher </listener-class> </listener>

这样spring security会监听session的listener。
到这里就知道Spring Security 和Spring Session是如何协作的了。

以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值