春季OAuth2重复登录

huangapple go评论73阅读模式
英文:

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);
}
  1. 并发会话控制--

当已经经过身份验证的用户尝试再次进行身份验证时,应用程序可以以以下几种方式处理该事件。它可以使用户的活动会话无效,并使用新会话再次对用户进行身份验证,或者允许两个会话同时存在。

启用并发会话控制支持的第一步是在 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&#39;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)
}
  1. 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:

&lt;listener&gt;
 &lt;listener-class&gt;
   org.springframework.security.web.session.HttpSessionEventPublisher
 &lt;/listener-class&gt;
&lt;/listener&gt;

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:

&lt;http ...&gt;
 &lt;session-management&gt;
    &lt;concurrency-control max-sessions=&quot;2&quot; /&gt;
 &lt;/session-management&gt;
&lt;/http&gt;

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()
}

huangapple
  • 本文由 发表于 2020年10月11日 15:47:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/64301745.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定