springboot spring session redis spring security 相同用户单个session的解决方案

首先还是吐槽,百度了两天,尝试了十多种方案,各种重写,无效。。。。。最后,还是在官网找到解决方案。

哎。。。已经很多次了。官网。官网。官网。。以后要多看官网。

 

还是描述下需求吧。很简单,相同的用户登录时,只能保留最后一个session。防止多处登录。也不算是单点。

在开始贴代码之前,各位看官一定要注意条件

springboot+spring session redis+spring security ,使用java config方式。

可能不使用spring session redis 或者 spring security的情况,不会出现我的问题,因为不涉及redis session的控制。

 

一般情况下,如果使用spring自带的内存管理方式,非常简单就可以实现(没有尝试,看百度应该问题不大)

springsecurity配置中

@Override
	protected void configure(HttpSecurity http) throws Exception {
....
http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(false).expiredUrl("/login?expired");
		
	}

而使用了spring session  redis,则在spring security对登陆session控制的默认实现类SessionRegistryImpl中判断session时,无法获取正确的获取session。特别是重启应用后,基于内存的SessionRegistryImpl就会丢失session,而redis中的还存在。登陆成功的用户还能操作,而SessionRegistryImpl中,则没有任何session了。

所以,解决方案是,在springsecurity配置中,注册spring session redis 的sessionregistry。代码如下(20191024修改):

@Configuration
@Import({ SessionRedisConfig.class })
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启security注解
public class WebSecurityConfig<S extends Session> extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private FindByIndexNameSessionRepository<S> sessionRepository;
	
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {

		// 允许所有用户访问"/"和"/register"
		http.authorizeRequests().antMatchers("/", "/public/**","/static/**", "/login").permitAll()
				.antMatchers("/admin/**").hasRole("ADMIN")
				// 其他地址的访问均需验证权限
				.anyRequest().authenticated()// .hasRole("USER")
				.and().formLogin()
				// 指定登录页是"/login"
				.loginPage("/login")
				// .failureUrl("/login?error=true")
				.defaultSuccessUrl("/main").permitAll()
				.and().headers().frameOptions().disable().and().logout()
				.logoutUrl("/logout").logoutSuccessUrl("/").permitAll();
		http.exceptionHandling().accessDeniedPage("/403")
			.and().csrf().disable();
		//not create new session
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
		//ori session user
		http.sessionManagement().sessionFixation().none();
		http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(false).expiredUrl("/login")
		.sessionRegistry(sessionRegistry());
		//http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
	}
	
	@Bean
    SpringSessionBackedSessionRegistry<S> sessionRegistry() {
            return new SpringSessionBackedSessionRegistry<S>(sessionRepository);
    }
	
	

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架。它简化了Spring应用程序的配置和部署过程,提供了一种快速开发的方式。Spring SecuritySpring框架的一个模块,用于处理应用程序的安全性需求。它提供了身份验证、授权、密码加密等功能,可以帮助开发者构建安全可靠的应用程序。 在Spring Boot中整合Spring Security可以通过添加相应的依赖和配置来实现。首先,需要在项目的pom.xml文件中添加Spring Security的依赖。然后,在应用程序的配置文件中配置安全相关的信息,如用户认证方式、权限控制等。最后,可以使用注解或配置类来定义安全规则和访问控制。 Redis是一个开源的内存数据库,它提供了高性能的键值存储和数据结构操作功能。在Spring Boot中整合Redis可以通过添加相应的依赖和配置来实现。首先,需要在项目的pom.xml文件中添加Redis的依赖。然后,在应用程序的配置文件中配置Redis的连接信息和相关参数。最后,可以使用Spring Data Redis提供的API来进行数据操作。 Oracle是一种关系型数据库管理系统,它提供了可靠的数据存储和高效的数据查询功能。在Spring Boot中整合Oracle可以通过添加相应的依赖和配置来实现。首先,需要在项目的pom.xml文件中添加Oracle数据库驱动的依赖。然后,在应用程序的配置文件中配置Oracle数据库的连接信息和相关参数。最后,可以使用Spring Data JPA提供的API来进行数据操作。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值