spring security session-management

本文介绍了如何使用Spring Security进行会话管理配置,包括限制用户的并发登录、设置过期URL等,通过具体代码示例展示了如何实现防止同一用户多次登录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、在配置文件中增加 一个listen

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

 2、FilterChainProxy 增加 ConcurrentSessionFilter ,这个Filter 要两个属性 sessionRegistry(需要SessionRegistryImpl实例expiredUrl过滤失败时跳转的url

<http>
<custom-filter position="FORM_LOGIN_FILTER" ref="loginFilter" />
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrentSessionFilter" />
<!-- 防止同一用户多次登录,使第二次登录失 -->
<session-management session-authentication-strategy-ref="concurrentSessionControlStrategy" />
</http>
<!-- Login Filter -->
<beans:bean id="loginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
	 <beans:property name="sessionAuthenticationStrategy" ref="concurrentSessionControlStrategy" />
	<beans:property name="authenticationManager" ref="authenticationManager" />
	<beans:property name="authenticationSuccessHandler" ref="loginAuthenticationSuccessHandler" />
	<beans:property name="authenticationFailureHandler" ref="loginAuthenticationFailureHandler" />
</beans:bean>
<beans:bean id="concurrentSessionFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
		<beans:property name="sessionRegistry" ref="sessionRegistry" />
		<beans:property name="expiredUrl" value="/admin/login" />
		<beans:property name="logoutHandlers">
			<beans:list>
				<beans:ref bean="logoutHandler" />
			</beans:list>
		</beans:property>
	</beans:bean>
<beans:bean id="logoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
<!-- the flowing settings for session management -->
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="concurrentSessionControlStrategy" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
		<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
		<beans:property name="maximumSessions" value="1" />
		<beans:property name="migrateSessionAttributes" value="true" />
		<beans:property name="exceptionIfMaximumExceeded" value="false" />
</beans:bean>

 3、代码  AbstractAuthenticationProcessingFilter  在方法dofilter()根据属性 concurrentSessionControlStrategy的方法onAuthentication

在ConcurrentSessionFilter Filter 中做具体是通过还是不过的验证

  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        HttpSession session = request.getSession(false);

        if (session != null) {
            SessionInformation info = sessionRegistry.getSessionInformation(session.getId());

            if (info != null) {
                if (info.isExpired()) {
                    // Expired - abort processing
                    doLogout(request, response);

                    String targetUrl = determineExpiredUrl(request, info);

                    if (targetUrl != null) {
                        redirectStrategy.sendRedirect(request, response, targetUrl);

                        return;
                    } else {
                        response.getWriter().print("This session has been expired (possibly due to multiple concurrent " +
                                "logins being attempted as the same user).");
                        response.flushBuffer();
                    }

                    return;
                } else {
                    // Non-expired - update last request date/time
                    sessionRegistry.refreshLastRequest(info.getSessionId());
                }
            }
        }

        chain.doFilter(request, response);
    }

 

李永博客的主页

Spring MVC 5.2 版本整合 Spring Session with Redis 2.2 主要是为了在分布式环境中利用缓存技术来管理和同步用户的会话数据,使得应用程序可以在多个节点上同时提供服务。下面是基本步骤: 1. 添加依赖:在你的 Maven 或 Gradle 项目中添加以下依赖: ```xml <!-- Maven --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>2.2.x</version> </dependency> <!-- Gradle --> implementation 'org.springframework.session:spring-session-data-redis:2.2.x' ``` 2. 配置 Redis:在 `application.properties` 或 `application.yml` 中配置 Redis 连接信息: ```properties spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=<your_redis_password> ``` 3. 创建 RedisTemplate:创建并配置 RedisTemplate,用于操作 Redis 数据库。 ```java @Bean public RedisTemplate<String, HttpSession> sessionRedisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, HttpSession> template = new RedisOperationsSessionRepository<>(factory); Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jsonSerializer.setObjectMapper(om); template.setValueSerializer(jsonSerializer); template.setKeySerializer(new StringRedisSerializer()); return template; } ``` 4. 配置 Spring Session:在 Spring 容器中开启 session 管理。 ```java @Configuration @EnableWebMvc @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private HttpSessionEventPublisher publisher; @Bean public HttpSessionStrategy httpSessionStrategy() { return new DefaultSavedRequestAwareSessionStrategy(); } @Override protected void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .formLogin() .disable() .and() .logout() .logoutSuccessUrl("/") .deleteCookies("JSESSIONID") .invalidateHttpSession(true); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 如果有需要,可以在此处配置认证机制 } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { SimpleCacheManager manager = new SimpleCacheManager(); manager.setCacheNames(Arrays.asList("sessions")); RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(15)) .serializeKeysWith(RedisSerializationSupport.STRING) .serializeValuesWith(jsonSerializer); manager.setCacheDefaults(config); return manager; } } ``` 5. 启用 Spring Session 支持:在 `WebMvcConfigurer` 接口中配置 session 存储: ```java @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // 如果你想支持序列化/反序列化 JSON,这里添加一个 Jackson2JsonHttpMessageConverter } } ``` 完成上述步骤后,Spring MVC 5.2 就已经整合了 Spring Session with Redis 2.2,会话数据会被存储在 Redis 中,提供分布式场景下的会话管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值