英文:
Spring Oauth2 duplicate logins
问题
以下是翻译好的部分:
我正在使用Spring Oauth2与自定义提供程序和Mongo会话。
当已经登录的用户导航到授权端点时,Spring会为用户创建一个新的会话。我可以在MongoDB上看到用户的多个重复会话。
有没有办法阻止这种情况发生?
即,如果用户已经登录,请使用当前的Principal和会话,而不是创建一个新的。
配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors()
.and()
.authorizeRequests()
.antMatchers("/auth/**", "/oauth2/**", "/v1/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.authorizationEndpoint()
.baseUri("/oauth2/authorize")
.and()
.redirectionEndpoint()
.baseUri("/auth/callback/*");
}
英文:
I'm using Spring Oauth2 with a custom provider and Mongo session.
When a user who is already logged in navigates to the authorization endpoint, Spring creates a new session for the user. I can see multiple duplicate sessions on mongoDB for the user.
Is there a way to prevent this?
i.e. If the user is already logged in, use the current Principal and session instead of creating a new one.
Configuration:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors()
.and()
.authorizeRequests()
.antMatchers("/auth/**", "/oauth2/**", "/v1/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.authorizationEndpoint()
.baseUri("/oauth2/authorize")
.and()
.redirectionEndpoint()
.baseUri("/auth/callback/*");
}
答案1
得分: 1
你必须在这种情况下禁用或控制会话。
- always – 如果不存在会话,将始终创建会话
- ifRequired – 仅在需要时创建会话(默认)
- never – 框架永远不会自行创建会话,但如果会话已存在,则会使用现有会话
- stateless – Spring Security 不会创建或使用任何会话
Java 配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
}
- 并发会话控制--
当已经经过身份验证的用户尝试再次进行身份验证时,应用程序可以以以下几种方式处理该事件。它可以使用户的活动会话无效,并使用新会话再次对用户进行身份验证,或者允许两个会话同时存在。
启用并发会话控制支持的第一步是在 web.xml 中添加以下监听器:
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
或者将其定义为 Bean,如下所示:
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
这对于确保在会话销毁时通知 Spring Security 会话注册表非常重要。
要启用允许同一用户的多个并发会话的情况,应在 XML 配置中使用 <session-management>
元素:
<http ...>
<session-management>
<concurrency-control max-sessions="2" />
</session-management>
</http>
或通过 Java 配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().maximumSessions(2);
}
请查看以下链接 --
https://www.baeldung.com/spring-security-session
英文:
You have to disable or control the session in this case.
always – a session will always be created if one
doesn't already exist
ifRequired – a session will be created only if
required (default)
never – the framework will never create a
session itself but it will use one if it already
exists
stateless – no session will be created or used
by Spring Security
Java configuration:
@Override
protected void configure(HttpSecurity http)
throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
}
- Concurrent Session Control--
When a user that is already authenticated tries to authenticate again, the application can deal with that event in one of a few ways. It can either invalidate the active session of the user and authenticate the user again with a new session, or allow both sessions to exist concurrently.
The first step in enabling the concurrent session-control support is to add the following listener in the web.xml:
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
Or define it as a Bean – as follows:
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
This is essential to make sure that the Spring Security session registry is notified when the session is destroyed.
To enable the scenario which allows multiple concurrent sessions for the same user the <session-management> element should be used in the XML configuration:
<http ...>
<session-management>
<concurrency-control max-sessions="2" />
</session-management>
</http>
Or, via Java configuration:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().maximumSessions(2)
}
Please have a look the following link --
https://www.baeldung.com/spring-security-session
答案2
得分: 1
经过一些研究,我发现这种行为是由于Spring的会话固定攻击保护所致。
默认情况下,Spring在重新验证身份时会迁移会话,这使得Spring通过复制先前会话中的现有属性为用户创建一个新会话。
然而,当发生这种情况时,spring-session-data-mongodb
由于某种原因不会删除旧的、无效的会话。我不确定为什么spring-session-data-mongodb
不会删除旧会话,所以如果有人知道如何改变这一点,请告诉我。
然而,如果您想改变这种行为,您可以将会话固定设置更改为以下内容,以便在重新验证身份时Spring使用现有的会话ID:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionFixation().none()
}
英文:
After some research I found out that this behavior is due to Spring's session fixation attack protection.
By default Spring migrates sessions on reauthentication, which makes Spring create a new session for the user by copying the existing attributes from the previous session.
When this happens however, spring-session-data-mongodb
does not delete the old, invalidated session for some reason. I am not sure why spring-session-data-mongodb
does not remove the old session, so if anyone has any idea on how to change this please let me know.
However, if you want to change this behavior, you can change the session fixation settings to the following to make spring use the existing session ID on reauthentication:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionFixation().none()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论