# Advanced Configuration `HttpSecurity.oauth2Login()` provides a number of configuration options for customizing OAuth 2.0 Login. The main configuration options are grouped into their protocol endpoint counterparts. For example, `oauth2Login().authorizationEndpoint()` allows configuring the *Authorization Endpoint*, whereas `oauth2Login().tokenEndpoint()` allows configuring the *Token Endpoint*. The following code shows an example: Example 1. Advanced OAuth2 Login Configuration Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .authorizationEndpoint(authorization -> authorization ... ) .redirectionEndpoint(redirection -> redirection ... ) .tokenEndpoint(token -> token ... ) .userInfoEndpoint(userInfo -> userInfo ... ) ); } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { authorizationEndpoint { ... } redirectionEndpoint { ... } tokenEndpoint { ... } userInfoEndpoint { ... } } } } } ``` The main goal of the `oauth2Login()` DSL was to closely align with the naming, as defined in the specifications. The OAuth 2.0 Authorization Framework defines the [Protocol Endpoints](https://tools.ietf.org/html/rfc6749#section-3) as follows: The authorization process utilizes two authorization server endpoints (HTTP resources): * Authorization Endpoint: Used by the client to obtain authorization from the resource owner via user-agent redirection. * Token Endpoint: Used by the client to exchange an authorization grant for an access token, typically with client authentication. As well as one client endpoint: * Redirection Endpoint: Used by the authorization server to return responses containing authorization credentials to the client via the resource owner user-agent. The OpenID Connect Core 1.0 specification defines the [UserInfo Endpoint](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo) as follows: The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns claims about the authenticated end-user. To obtain the requested claims about the end-user, the client makes a request to the UserInfo Endpoint by using an access token obtained through OpenID Connect Authentication. These claims are normally represented by a JSON object that contains a collection of name-value pairs for the claims. The following code shows the complete configuration options available for the `oauth2Login()` DSL: Example 2. OAuth2 Login Configuration Options Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .clientRegistrationRepository(this.clientRegistrationRepository()) .authorizedClientRepository(this.authorizedClientRepository()) .authorizedClientService(this.authorizedClientService()) .loginPage("/login") .authorizationEndpoint(authorization -> authorization .baseUri(this.authorizationRequestBaseUri()) .authorizationRequestRepository(this.authorizationRequestRepository()) .authorizationRequestResolver(this.authorizationRequestResolver()) ) .redirectionEndpoint(redirection -> redirection .baseUri(this.authorizationResponseBaseUri()) ) .tokenEndpoint(token -> token .accessTokenResponseClient(this.accessTokenResponseClient()) ) .userInfoEndpoint(userInfo -> userInfo .userAuthoritiesMapper(this.userAuthoritiesMapper()) .userService(this.oauth2UserService()) .oidcUserService(this.oidcUserService()) ) ); } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { clientRegistrationRepository = clientRegistrationRepository() authorizedClientRepository = authorizedClientRepository() authorizedClientService = authorizedClientService() loginPage = "/login" authorizationEndpoint { baseUri = authorizationRequestBaseUri() authorizationRequestRepository = authorizationRequestRepository() authorizationRequestResolver = authorizationRequestResolver() } redirectionEndpoint { baseUri = authorizationResponseBaseUri() } tokenEndpoint { accessTokenResponseClient = accessTokenResponseClient() } userInfoEndpoint { userAuthoritiesMapper = userAuthoritiesMapper() userService = oauth2UserService() oidcUserService = oidcUserService() } } } } } ``` In addition to the `oauth2Login()` DSL, XML configuration is also supported. The following code shows the complete configuration options available in the [ security namespace](../../appendix/namespace/http.html#nsa-oauth2-login): Example 3. OAuth2 Login XML Configuration Options ``` ``` The following sections go into more detail on each of the configuration options available: * [OAuth 2.0 Login Page](#oauth2login-advanced-login-page) * [Redirection Endpoint](#oauth2login-advanced-redirection-endpoint) * [UserInfo Endpoint](#oauth2login-advanced-userinfo-endpoint) * [ID Token Signature Verification](#oauth2login-advanced-idtoken-verify) * [OpenID Connect 1.0 Logout](#oauth2login-advanced-oidc-logout) ## OAuth 2.0 Login Page By default, the OAuth 2.0 Login Page is auto-generated by the `DefaultLoginPageGeneratingFilter`. The default login page shows each configured OAuth Client with its `ClientRegistration.clientName` as a link, which is capable of initiating the Authorization Request (or OAuth 2.0 Login). | |In order for `DefaultLoginPageGeneratingFilter` to show links for configured OAuth Clients, the registered `ClientRegistrationRepository` needs to also implement `Iterable`.
See `InMemoryClientRegistrationRepository` for reference.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| The link’s destination for each OAuth Client defaults to the following: `OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/{registrationId}"` The following line shows an example: ``` Google ``` To override the default login page, configure `oauth2Login().loginPage()` and (optionally) `oauth2Login().authorizationEndpoint().baseUri()`. The following listing shows an example: Example 4. OAuth2 Login Page Configuration Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .loginPage("/login/oauth2") ... .authorizationEndpoint(authorization -> authorization .baseUri("/login/oauth2/authorization") ... ) ); } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { loginPage = "/login/oauth2" authorizationEndpoint { baseUri = "/login/oauth2/authorization" } } } } } ``` Xml ``` ``` | |You need to provide a `@Controller` with a `@RequestMapping("/login/oauth2")` that is capable of rendering the custom login page.| |---|---------------------------------------------------------------------------------------------------------------------------------| | |As noted earlier, configuring `oauth2Login().authorizationEndpoint().baseUri()` is optional.
However, if you choose to customize it, ensure the link to each OAuth Client matches the `authorizationEndpoint().baseUri()`.

The following line shows an example:

```
Google
```| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ## Redirection Endpoint The Redirection Endpoint is used by the Authorization Server for returning the Authorization Response (which contains the authorization credentials) to the client via the Resource Owner user-agent. | |OAuth 2.0 Login leverages the Authorization Code Grant.
Therefore, the authorization credential is the authorization code.| |---|------------------------------------------------------------------------------------------------------------------------------| The default Authorization Response `baseUri` (redirection endpoint) is `**/login/oauth2/code/***`, which is defined in `OAuth2LoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI`. If you would like to customize the Authorization Response `baseUri`, configure it as shown in the following example: Example 5. Redirection Endpoint Configuration Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .redirectionEndpoint(redirection -> redirection .baseUri("/login/oauth2/callback/*") ... ) ); } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { redirectionEndpoint { baseUri = "/login/oauth2/callback/*" } } } } } ``` Xml ``` ``` | |You also need to ensure the `ClientRegistration.redirectUri` matches the custom Authorization Response `baseUri`.

The following listing shows an example:

Java

```
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.redirectUri("{baseUrl}/login/oauth2/callback/{registrationId}")
.build();
```

Kotlin

```
return CommonOAuth2Provider.GOOGLE.getBuilder("google")
.clientId("google-client-id")
.clientSecret("google-client-secret")
.redirectUri("{baseUrl}/login/oauth2/callback/{registrationId}")
.build()
```| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ## UserInfo Endpoint The UserInfo Endpoint includes a number of configuration options, as described in the following sub-sections: * [Mapping User Authorities](#oauth2login-advanced-map-authorities) * [OAuth 2.0 UserService](#oauth2login-advanced-oauth2-user-service) * [OpenID Connect 1.0 UserService](#oauth2login-advanced-oidc-user-service) ### Mapping User Authorities After the user successfully authenticates with the OAuth 2.0 Provider, the `OAuth2User.getAuthorities()` (or `OidcUser.getAuthorities()`) may be mapped to a new set of `GrantedAuthority` instances, which will be supplied to `OAuth2AuthenticationToken` when completing the authentication. | |`OAuth2AuthenticationToken.getAuthorities()` is used for authorizing requests, such as in `hasRole('USER')` or `hasRole('ADMIN')`.| |---|----------------------------------------------------------------------------------------------------------------------------------| There are a couple of options to choose from when mapping user authorities: * [Using a GrantedAuthoritiesMapper](#oauth2login-advanced-map-authorities-grantedauthoritiesmapper) * [Delegation-based strategy with OAuth2UserService](#oauth2login-advanced-map-authorities-oauth2userservice) #### Using a GrantedAuthoritiesMapper Provide an implementation of `GrantedAuthoritiesMapper` and configure it as shown in the following example: Example 6. Granted Authorities Mapper Configuration Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .userInfoEndpoint(userInfo -> userInfo .userAuthoritiesMapper(this.userAuthoritiesMapper()) ... ) ); } private GrantedAuthoritiesMapper userAuthoritiesMapper() { return (authorities) -> { Set mappedAuthorities = new HashSet<>(); authorities.forEach(authority -> { if (OidcUserAuthority.class.isInstance(authority)) { OidcUserAuthority oidcUserAuthority = (OidcUserAuthority)authority; OidcIdToken idToken = oidcUserAuthority.getIdToken(); OidcUserInfo userInfo = oidcUserAuthority.getUserInfo(); // Map the claims found in idToken and/or userInfo // to one or more GrantedAuthority's and add it to mappedAuthorities } else if (OAuth2UserAuthority.class.isInstance(authority)) { OAuth2UserAuthority oauth2UserAuthority = (OAuth2UserAuthority)authority; Map userAttributes = oauth2UserAuthority.getAttributes(); // Map the attributes found in userAttributes // to one or more GrantedAuthority's and add it to mappedAuthorities } }); return mappedAuthorities; }; } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { userInfoEndpoint { userAuthoritiesMapper = userAuthoritiesMapper() } } } } private fun userAuthoritiesMapper(): GrantedAuthoritiesMapper = GrantedAuthoritiesMapper { authorities: Collection -> val mappedAuthorities = emptySet() authorities.forEach { authority -> if (authority is OidcUserAuthority) { val idToken = authority.idToken val userInfo = authority.userInfo // Map the claims found in idToken and/or userInfo // to one or more GrantedAuthority's and add it to mappedAuthorities } else if (authority is OAuth2UserAuthority) { val userAttributes = authority.attributes // Map the attributes found in userAttributes // to one or more GrantedAuthority's and add it to mappedAuthorities } } mappedAuthorities } } ``` Xml ``` ``` Alternatively, you may register a `GrantedAuthoritiesMapper` `@Bean` to have it automatically applied to the configuration, as shown in the following example: Example 7. Granted Authorities Mapper Bean Configuration Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(withDefaults()); } @Bean public GrantedAuthoritiesMapper userAuthoritiesMapper() { ... } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { } } } @Bean fun userAuthoritiesMapper(): GrantedAuthoritiesMapper { ... } } ``` #### Delegation-based strategy with OAuth2UserService This strategy is advanced compared to using a `GrantedAuthoritiesMapper`, however, it’s also more flexible as it gives you access to the `OAuth2UserRequest` and `OAuth2User` (when using an OAuth 2.0 UserService) or `OidcUserRequest` and `OidcUser` (when using an OpenID Connect 1.0 UserService). The `OAuth2UserRequest` (and `OidcUserRequest`) provides you access to the associated `OAuth2AccessToken`, which is very useful in the cases where the *delegator* needs to fetch authority information from a protected resource before it can map the custom authorities for the user. The following example shows how to implement and configure a delegation-based strategy using an OpenID Connect 1.0 UserService: Example 8. OAuth2UserService Configuration Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .userInfoEndpoint(userInfo -> userInfo .oidcUserService(this.oidcUserService()) ... ) ); } private OAuth2UserService oidcUserService() { final OidcUserService delegate = new OidcUserService(); return (userRequest) -> { // Delegate to the default implementation for loading a user OidcUser oidcUser = delegate.loadUser(userRequest); OAuth2AccessToken accessToken = userRequest.getAccessToken(); Set mappedAuthorities = new HashSet<>(); // TODO // 1) Fetch the authority information from the protected resource using accessToken // 2) Map the authority information to one or more GrantedAuthority's and add it to mappedAuthorities // 3) Create a copy of oidcUser but use the mappedAuthorities instead oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo()); return oidcUser; }; } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { userInfoEndpoint { oidcUserService = oidcUserService() } } } } @Bean fun oidcUserService(): OAuth2UserService { val delegate = OidcUserService() return OAuth2UserService { userRequest -> // Delegate to the default implementation for loading a user var oidcUser = delegate.loadUser(userRequest) val accessToken = userRequest.accessToken val mappedAuthorities = HashSet() // TODO // 1) Fetch the authority information from the protected resource using accessToken // 2) Map the authority information to one or more GrantedAuthority's and add it to mappedAuthorities // 3) Create a copy of oidcUser but use the mappedAuthorities instead oidcUser = DefaultOidcUser(mappedAuthorities, oidcUser.idToken, oidcUser.userInfo) oidcUser } } } ``` Xml ``` ``` ### OAuth 2.0 UserService `DefaultOAuth2UserService` is an implementation of an `OAuth2UserService` that supports standard OAuth 2.0 Provider’s. | |`OAuth2UserService` obtains the user attributes of the end-user (the resource owner) from the UserInfo Endpoint (by using the access token granted to the client during the authorization flow) and returns an `AuthenticatedPrincipal` in the form of an `OAuth2User`.| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| `DefaultOAuth2UserService` uses a `RestOperations` when requesting the user attributes at the UserInfo Endpoint. If you need to customize the pre-processing of the UserInfo Request, you can provide `DefaultOAuth2UserService.setRequestEntityConverter()` with a custom `Converter>`. The default implementation `OAuth2UserRequestEntityConverter` builds a `RequestEntity` representation of a UserInfo Request that sets the `OAuth2AccessToken` in the `Authorization` header by default. On the other end, if you need to customize the post-handling of the UserInfo Response, you will need to provide `DefaultOAuth2UserService.setRestOperations()` with a custom configured `RestOperations`. The default `RestOperations` is configured as follows: ``` RestTemplate restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); ``` `OAuth2ErrorResponseErrorHandler` is a `ResponseErrorHandler` that can handle an OAuth 2.0 Error (400 Bad Request). It uses an `OAuth2ErrorHttpMessageConverter` for converting the OAuth 2.0 Error parameters to an `OAuth2Error`. Whether you customize `DefaultOAuth2UserService` or provide your own implementation of `OAuth2UserService`, you’ll need to configure it as shown in the following example: Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .userInfoEndpoint(userInfo -> userInfo .userService(this.oauth2UserService()) ... ) ); } private OAuth2UserService oauth2UserService() { ... } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { userInfoEndpoint { userService = oauth2UserService() // ... } } } } private fun oauth2UserService(): OAuth2UserService { // ... } } ``` ### OpenID Connect 1.0 UserService `OidcUserService` is an implementation of an `OAuth2UserService` that supports OpenID Connect 1.0 Provider’s. The `OidcUserService` leverages the `DefaultOAuth2UserService` when requesting the user attributes at the UserInfo Endpoint. If you need to customize the pre-processing of the UserInfo Request and/or the post-handling of the UserInfo Response, you will need to provide `OidcUserService.setOauth2UserService()` with a custom configured `DefaultOAuth2UserService`. Whether you customize `OidcUserService` or provide your own implementation of `OAuth2UserService` for OpenID Connect 1.0 Provider’s, you’ll need to configure it as shown in the following example: Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .oauth2Login(oauth2 -> oauth2 .userInfoEndpoint(userInfo -> userInfo .oidcUserService(this.oidcUserService()) ... ) ); } private OAuth2UserService oidcUserService() { ... } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { override fun configure(http: HttpSecurity) { http { oauth2Login { userInfoEndpoint { oidcUserService = oidcUserService() // ... } } } } private fun oidcUserService(): OAuth2UserService { // ... } } ``` ## ID Token Signature Verification OpenID Connect 1.0 Authentication introduces the [ID Token](https://openid.net/specs/openid-connect-core-1_0.html#IDToken), which is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when used by a Client. The ID Token is represented as a [JSON Web Token](https://tools.ietf.org/html/rfc7519) (JWT) and MUST be signed using [JSON Web Signature](https://tools.ietf.org/html/rfc7515) (JWS). The `OidcIdTokenDecoderFactory` provides a `JwtDecoder` used for `OidcIdToken` signature verification. The default algorithm is `RS256` but may be different when assigned during client registration. For these cases, a resolver may be configured to return the expected JWS algorithm assigned for a specific client. The JWS algorithm resolver is a `Function` that accepts a `ClientRegistration` and returns the expected `JwsAlgorithm` for the client, eg. `SignatureAlgorithm.RS256` or `MacAlgorithm.HS256` The following code shows how to configure the `OidcIdTokenDecoderFactory` `@Bean` to default to `MacAlgorithm.HS256` for all `ClientRegistration`: Java ``` @Bean public JwtDecoderFactory idTokenDecoderFactory() { OidcIdTokenDecoderFactory idTokenDecoderFactory = new OidcIdTokenDecoderFactory(); idTokenDecoderFactory.setJwsAlgorithmResolver(clientRegistration -> MacAlgorithm.HS256); return idTokenDecoderFactory; } ``` Kotlin ``` @Bean fun idTokenDecoderFactory(): JwtDecoderFactory { val idTokenDecoderFactory = OidcIdTokenDecoderFactory() idTokenDecoderFactory.setJwsAlgorithmResolver { MacAlgorithm.HS256 } return idTokenDecoderFactory } ``` | |For MAC based algorithms such as `HS256`, `HS384` or `HS512`, the `client-secret` corresponding to the `client-id` is used as the symmetric key for signature verification.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | |If more than one `ClientRegistration` is configured for OpenID Connect 1.0 Authentication, the JWS algorithm resolver may evaluate the provided `ClientRegistration` to determine which algorithm to return.| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ## OpenID Connect 1.0 Logout OpenID Connect Session Management 1.0 allows the ability to log out the End-User at the Provider using the Client. One of the strategies available is [RP-Initiated Logout](https://openid.net/specs/openid-connect-session-1_0.html#RPLogout). If the OpenID Provider supports both Session Management and [Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html), the client may obtain the `end_session_endpoint` `URL` from the OpenID Provider’s [Discovery Metadata](https://openid.net/specs/openid-connect-session-1_0.html#OPMetadata). This can be achieved by configuring the `ClientRegistration` with the `issuer-uri`, as in the following example: ``` spring: security: oauth2: client: registration: okta: client-id: okta-client-id client-secret: okta-client-secret ... provider: okta: issuer-uri: https://dev-1234.oktapreview.com ``` …​and the `OidcClientInitiatedLogoutSuccessHandler`, which implements RP-Initiated Logout, may be configured as follows: Java ``` @EnableWebSecurity public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private ClientRegistrationRepository clientRegistrationRepository; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated() ) .oauth2Login(withDefaults()) .logout(logout -> logout .logoutSuccessHandler(oidcLogoutSuccessHandler()) ); } private LogoutSuccessHandler oidcLogoutSuccessHandler() { OidcClientInitiatedLogoutSuccessHandler oidcLogoutSuccessHandler = new OidcClientInitiatedLogoutSuccessHandler(this.clientRegistrationRepository); // Sets the location that the End-User's User Agent will be redirected to // after the logout has been performed at the Provider oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}"); return oidcLogoutSuccessHandler; } } ``` Kotlin ``` @EnableWebSecurity class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() { @Autowired private lateinit var clientRegistrationRepository: ClientRegistrationRepository override fun configure(http: HttpSecurity) { http { authorizeRequests { authorize(anyRequest, authenticated) } oauth2Login { } logout { logoutSuccessHandler = oidcLogoutSuccessHandler() } } } private fun oidcLogoutSuccessHandler(): LogoutSuccessHandler { val oidcLogoutSuccessHandler = OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository) // Sets the location that the End-User's User Agent will be redirected to // after the logout has been performed at the Provider oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}") return oidcLogoutSuccessHandler } } ``` | |`OidcClientInitiatedLogoutSuccessHandler` supports the `{baseUrl}` placeholder.
If used, the application’s base URL, like `[https://app.example.org](https://app.example.org)`, will replace it at request time.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| [Core Configuration](core.html)[OAuth2 Client](../client/index.html)