我们最近开始在我们的项目中使用 spring-session。这是一个遗留应用程序,我们有一些HttpSessionListener。因此,当会话过期或用户无效时,将sessionDestroyed(HttpSessionEvent se)调用会话方法。您可以HttpSession通过调用getSession()方法来获取即将被销毁的HttpSessionEvent
Spring session 也有类似的东西。Redis Session Repository 实现将触发org.springframework.session.events.SessionDestroyedEvent事件,您可以向其添加ApplicationListener以进行一些处理。
但这并不能满足我的需要。
我遇到的问题是,即使由于 2 个主要原因,它也不能用于迁移我们现有的 HttpSessionListener 以使用这些
Spring Session 触发的事件只给出即将被销毁的会话 id。它不提供整个会话对象的副本。所以如果我现有的 HttpSessionListener 有一些逻辑来使用某些属性进行某些处理,我现在不能这样做。
创建会话时没有事件。我们有 HttpSessionListener 在创建会话时会做一些工作。
那么我有什么所有选项才能获得我们在 Spring 会话中使用 HttpSessionListener 工作的功能?
当尝试将 spring-session 添加到具有 spring-security 的现有 Spring MVC 项目时,我得到以下行为(编辑:tomcat 的 session-timeout 设置为 1 分钟以进行测试):
除此之外,一切似乎都按预期工作 - 会话在 redis 中持续存在并跨 webapp 重新启动,并且手动注销正确地使会话无效。
我的一些配置片段 - 这是 spring-security 的无效会话处理程序配置,这将导致过期的会话被重定向到登录页面:
...
<beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg name="securityContextRepository">
<beans:bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
</beans:constructor-arg>
<beans:property name="invalidSessionStrategy">
<beans:bean class="my.CustomInvalidSessionStrategy"/>
</beans:property>
</beans:bean>
...
<http>
...
<custom-filter position="SESSION_MANAGEMENT_FILTER" ref="sessionManagementFilter"/>
...
<logout delete-cookies="true" invalidate-session="true" logout-url="/signout.html" success-handler-ref="logoutSuccessHandler"/>
</http>
Run Code Online (Sandbox Code Playgroud)
web.xml 的过滤器链如下所示:
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> …Run Code Online (Sandbox Code Playgroud) 我使用 OpenAM 作为我的 IDP,我的 SP(angular2 SPA)基于以下共享的示例:https : //github.com/vdenotaris/spring-boot-security-saml-sample
身份验证后,我的 webapp 应该调用一些 REST 服务,这些服务通过 http-basic 身份验证(使用 spring 安全性)保护,其会话通过Spring Session进行管理。
在用户通过 OpenAM IDP 进行身份验证后,我正在尝试创建基于 spring 会话的会话。我的目的是使用这些会话与我的 http-basic-secured REST 服务进行对话。
以下是在我尝试将 spring-session 与 spring-saml 集成之前,我的 webapp 的 WebSecurityConfig 的“configure()”,这工作得很好。
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.authenticationEntryPoint(samlEntryPoint());
http
.csrf()
.disable();
http
.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/publicUrl").permitAll()
.antMatchers("/app/**").permitAll()
.antMatchers("/error").permitAll()
.antMatchers("/saml/**").permitAll()
.anyRequest().authenticated();
http
.logout()
.logoutSuccessUrl("/");
}
Run Code Online (Sandbox Code Playgroud)
并且身份验证工作得很好。在从 IDP (OpenAM) 发出的 POST 中,我可以看到 cookie 被正确设置。例如:Set-Cookie:JSESSIONID=8DD6CDBF8079E83C8F4E7976C970BB27;路径=/;仅Http
Response
Headers …Run Code Online (Sandbox Code Playgroud) 我有一些Spring Boot,Spring Security,Spring Sessions和Spring Redis的应用程序.
我的一个应用程序(我将其称为"权限")负责为我的所有其他应用程序提供登录服务.这已经很好了.
现在,我想使用Permissions来管理所有其他应用程序的会话(例如创建,删除,获取和保存会话).权限将在Redis中持续存在.
权限本身是一个用于管理登录和会话的应用程序,一切正常(Redis上的登录和会话持久性).
要管理会话,我需要在权限中提供服务并在其他应用程序中使用此服务,但我没有ideia在两个应用程序中必须覆盖的会话过滤器或实现才能使此功能正常工作.
任何人都有一个想法来集中会话管理并应用新规则,如无效或在与所有其他系统的唯一点创建新会话?
我正在构建一个小型 websocket 项目并由 JWT 令牌机制保护,我想将 websocket 会话存储在 redis 而不是本地内存中。
@Override
protected void configureStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/hello")
.addInterceptors(new HttpSessionHandshakeInterceptor() {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
}
return true;
}
})
.withSockJS()
.setSessionCookieNeeded(true);
}
Run Code Online (Sandbox Code Playgroud)
我在我的 redis 配置中使用 @EnableRedisHttpSession 并且上面的源代码安全地将 http 会话存储在 redis 中,但即使我刷新了我的 redis 数据库,我仍然可以向我连接的客户端发送和接收我的消息。
我的猜测是 HttpSession 与 WebSocket 会话不同。如果您使用基于令牌的身份验证,我应该如何“智能地”要求 spring 在 redis 中存储和维护与 websocket …
目前我正在体验新的 Spring 反应式堆栈,并希望在 Spring Session 2.0 中使用反应式功能。
在传统的 Servlet 方法中,Spring Session 提供了一个HttpSessionStrategy来检测 cookie 或请求标头中的会话。它很容易用于为 RESTful APIHeaderHttpSessionStrategy实现类似身份验证的令牌(默认名称为X-AUTH-TOKEN)。
Spring 5核心提供了一个WebSessionIdResolver为Reactive环境做同样的事情。
但是当它与 Spring Security 一起使用并希望它以传统方式工作时,我无法让它工作。
会话配置文件。
@EnableSpringWebSession
public class SessionConfig {
@Bean
public ReactorSessionRepository sessionRepository() {
return new MapReactorSessionRepository(new ConcurrentHashMap<>());
}
@Bean
public WebSessionIdResolver headerWebSessionIdResolver() {
HeaderWebSessionIdResolver resolver = new HeaderWebSessionIdResolver();
resolver.setHeaderName("X-SESSION-ID");
return resolver;
}
}
Run Code Online (Sandbox Code Playgroud)
部分SecurityConfig。
@EnableWebFluxSecurity
class SecurityConfig {
@Bean
SecurityWebFilterChain springWebFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeExchange()
.pathMatchers(HttpMethod.GET, "/posts/**").permitAll()
.pathMatchers(HttpMethod.DELETE, "/posts/**").hasRole("ADMIN") …Run Code Online (Sandbox Code Playgroud) spring spring-security reactive-programming spring-session spring-webflux
我正在使用 Spring Boot 2.0.x、Hibernate 和 Spring Session Jdbc 以及 Mysql 5.7。我在开发环境下工作,因此 Hibernate 配置为每次生成模式:
spring.jpa.hibernate.ddl-auto=create-drop
Run Code Online (Sandbox Code Playgroud)
它工作正常,但我的 Spring Session 有问题......我尝试了 set initialize-schema,但它不起作用。
spring.session.jdbc.initialize-schema=always
Run Code Online (Sandbox Code Playgroud)
是否可以自动生成完整模式(所有实体和 SPRING_SESSION)?
它不适用于 MySQL 和 H2 (我尝试过embedded选项)
为什么 spring.session.store-type 没有 in memory 选项。?
有什么方法可以在不编写我的 store 实现的情况下使用带有内存选项的 spring 会话吗?
我想使用 spring 会话来使用令牌休息 api
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
Run Code Online (Sandbox Code Playgroud) 我正在 Spring 创建一个简单的酒店预订 Web 应用程序。目前,我正在构建预订功能的实际实现,使用 HttpSession 来存储对服务器的请求之间的数据。
请参阅以下预订流程:
第 1 步:url:“/”(索引页)- 用户选择位置、入住和退房日期
第 2 步:url:“/reservation/roomselection” - 用户从三种可用房间类型中选择一种
第 3 步:url:“/auth/guest/reservation/details” - 用户添加附加信息并确认预订
重要提示 在进入步骤 3 之前,用户需要在登录页面(url:“/login”)上进行身份验证,因此他会自动重定向到登录页面,并且在身份验证成功后重定向到步骤 3 的 url。
整个会话工作正常(应用程序记住了所有信息,直到第三步),直到我在步骤 3 之前引入了身份验证。登录后,所有信息都将丢失,并且 JSESSIONID cookie 将被重新创建(前一个信息将丢失)。
我确实了解该问题的原因 - 我的登录映射位于不同的控制器中,我想将其保留在那里。
我想问是否有任何简单的解决方案可以让我保留相同的SESSIONID和所有信息直到步骤3(登录页面之后)?
我的愿望如下:
我附上了 ReservationController、ReservationDto 以及 HomeController(带有登录页面)的代码。
感谢您的所有回答!
@Controller
@RequestMapping("/")
@SessionAttributes("reservationDto")
public class ReservationController {
private Logger LOG = LoggerFactory.getLogger(getClass());
private final HotelService hotelService;
public ReservationController(HotelService hotelService) {
this.hotelService = hotelService;
}
@GetMapping …Run Code Online (Sandbox Code Playgroud) 我正在使用 Spring Session Redis Data(使用自动配置进行配置,到目前为止没有自定义),它默认用作FindByIndexNameSessionRepository实现SessionRepository。
但是,有时在 Redis 中(在会话已过期但未执行注销之后),前缀为 的密钥的spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:TTL 仍为 -1,这意味着 Redis 不会使该密钥过期。
为什么 Spring Session(Redis 数据)在会话过期时不清理这个键?我在文档中也找不到提及。
我已按照文档中所述将带有主体名称的属性存储到会话中,但这并不能解决此问题。有关详细信息,请参阅https://docs.spring.io/spring-session/reference/api.html#api-findbyindexnamesessionrepository。
使用的Redis版本:6.2.6(bitnami/redis的docker镜像:6.2.6)
相关依赖:
我不希望索引持久化的原因是,如果有很多用户至少登录过一次并且有一个密钥持久化到Redis(其作用类似于索引),那么Redis将不得不存储可能无法访问的数据很长一段时间(或根本没有)。
spring-security spring-data-redis spring-boot spring-session
spring-session ×10
java ×4
spring ×4
spring-boot ×4
hibernate ×1
redis ×1
saml ×1
saml-2.0 ×1
session ×1
spring-mvc ×1
spring-saml ×1
stomp ×1