1
0
mirror of synced 2026-08-05 01:36:56 +00:00

Expose OidcBackChannelLogoutHandler

This component already uses by default a URI that doesn't require
a CSRF token and aalready allows for configuring a cookie name.

So, by making it public and configurable in the DSL, both
of these tickets quite naturally close.

Closes gh-13841
Closes gh-14904
This commit is contained in:
Josh Cummings
2024-07-22 16:58:49 -06:00
parent 2d4c498c3b
commit 8bb5875595
22 changed files with 910 additions and 137 deletions
@@ -137,6 +137,11 @@ Java::
+
[source,java,role="primary"]
----
@Bean
OidcBackChannelServerLogoutHandler oidcLogoutHandler() {
return new OidcBackChannelServerLogoutHandler();
}
@Bean
public SecurityWebFilterChain filterChain(ServerHttpSecurity http) throws Exception {
http
@@ -155,6 +160,11 @@ Kotlin::
+
[source,kotlin,role="secondary"]
----
@Bean
fun oidcLogoutHandler(): OidcBackChannelLogoutHandler {
return OidcBackChannelLogoutHandler()
}
@Bean
open fun filterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
http {
@@ -197,6 +207,80 @@ The overall flow for a Back-Channel logout is like this:
Remember that Spring Security's OIDC support is multi-tenant.
This means that it will only terminate sessions whose Client matches the `aud` claim in the Logout Token.
=== Customizing the Session Logout Endpoint
With `OidcBackChannelServerLogoutHandler` published, the session logout endpoint is `+{baseUrl}+/logout/connect/back-channel/+{registrationId}+`.
If `OidcBackChannelServerLogoutHandler` is not wired, then the URL is `+{baseUrl}+/logout/connect/back-channel/+{registrationId}+`, which is not recommended since it requires passing a CSRF token, which can be challenging depending on the kind of repository your application uses.
In the event that you need to customize the endpoint, you can provide the URL as follows:
[tabs]
======
Java::
+
[source=java,role="primary"]
----
http
// ...
.oidcLogout((oidc) -> oidc
.backChannel((backChannel) -> backChannel
.logoutUri("http://localhost:9000/logout/connect/back-channel/+{registrationId}+")
)
);
----
Kotlin::
+
[source=kotlin,role="secondary"]
----
http {
oidcLogout {
backChannel {
logoutUri = "http://localhost:9000/logout/connect/back-channel/+{registrationId}+"
}
}
}
----
======
=== Customizing the Session Logout Cookie Name
By default, the session logout endpoint uses the `JSESSIONID` cookie to correlate the session to the corresponding `OidcSessionInformation`.
However, the default cookie name in Spring Session is `SESSION`.
You can configure Spring Session's cookie name in the DSL like so:
[tabs]
======
Java::
+
[source=java,role="primary"]
----
@Bean
OidcBackChannelServerLogoutHandler oidcLogoutHandler(ReactiveOidcSessionRegistry sessionRegistry) {
OidcBackChannelServerLogoutHandler logoutHandler = new OidcBackChannelServerLogoutHandler(sessionRegistry);
logoutHandler.setSessionCookieName("SESSION");
return logoutHandler;
}
----
Kotlin::
+
[source=kotlin,role="secondary"]
----
@Bean
open fun oidcLogoutHandler(val sessionRegistry: ReactiveOidcSessionRegistry): OidcBackChannelServerLogoutHandler {
val logoutHandler = OidcBackChannelServerLogoutHandler(sessionRegistry)
logoutHandler.setSessionCookieName("SESSION")
return logoutHandler
}
----
======
[[oidc-backchannel-logout-session-registry]]
=== Customizing the OIDC Provider Session Registry
By default, Spring Security stores in-memory all links between the OIDC Provider session and the Client session.
@@ -136,6 +136,11 @@ Java::
+
[source,java,role="primary"]
----
@Bean
OidcBackChannelLogoutHandler oidcLogoutHandler() {
return new OidcBackChannelLogoutHandler();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
@@ -154,6 +159,11 @@ Kotlin::
+
[source,kotlin,role="secondary"]
----
@Bean
fun oidcLogoutHandler(): OidcBackChannelLogoutHandler {
return OidcBackChannelLogoutHandler()
}
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
@@ -223,6 +233,87 @@ The overall flow for a Back-Channel logout is like this:
Remember that Spring Security's OIDC support is multi-tenant.
This means that it will only terminate sessions whose Client matches the `aud` claim in the Logout Token.
One notable part of this architecture's implementation is that it propagates the incoming back-channel request internally for each corresponding session.
Initially, this may seem unnecessary.
However, recall that the Servlet API does not give direct access to the `HttpSession` store.
By making an internal logout call, the corresponding session can now be validated.
Additionally, forging a logout call internally allows for each set of ``LogoutHandler``s to be run against that session and corresponding `SecurityContext`.
=== Customizing the Session Logout Endpoint
With `OidcBackChannelLogoutHandler` published, the session logout endpoint is `+{baseUrl}+/logout/connect/back-channel/+{registrationId}+`.
If `OidcBackChannelLogoutHandler` is not wired, then the URL is `+{baseUrl}+/logout/connect/back-channel/+{registrationId}+`, which is not recommended since it requires passing a CSRF token, which can be challenging depending on the kind of repository your application uses.
In the event that you need to customize the endpoint, you can provide the URL as follows:
[tabs]
======
Java::
+
[source=java,role="primary"]
----
http
// ...
.oidcLogout((oidc) -> oidc
.backChannel((backChannel) -> backChannel
.logoutUri("http://localhost:9000/logout/connect/back-channel/+{registrationId}+")
)
);
----
Kotlin::
+
[source=kotlin,role="secondary"]
----
http {
oidcLogout {
backChannel {
logoutUri = "http://localhost:9000/logout/connect/back-channel/+{registrationId}+"
}
}
}
----
======
=== Customizing the Session Logout Cookie Name
By default, the session logout endpoint uses the `JSESSIONID` cookie to correlate the session to the corresponding `OidcSessionInformation`.
However, the default cookie name in Spring Session is `SESSION`.
You can configure Spring Session's cookie name in the DSL like so:
[tabs]
======
Java::
+
[source=java,role="primary"]
----
@Bean
OidcBackChannelLogoutHandler oidcLogoutHandler(OidcSessionRegistry sessionRegistry) {
OidcBackChannelLogoutHandler logoutHandler = new OidcBackChannelLogoutHandler(oidcSessionRegistry);
logoutHandler.setSessionCookieName("SESSION");
return logoutHandler;
}
----
Kotlin::
+
[source=kotlin,role="secondary"]
----
@Bean
open fun oidcLogoutHandler(val sessionRegistry: OidcSessionRegistry): OidcBackChannelLogoutHandler {
val logoutHandler = OidcBackChannelLogoutHandler(sessionRegistry)
logoutHandler.setSessionCookieName("SESSION")
return logoutHandler
}
----
======
[[oidc-backchannel-logout-session-registry]]
=== Customizing the OIDC Provider Session Registry
By default, Spring Security stores in-memory all links between the OIDC Provider session and the Client session.