diff --git a/spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/client/SpringAddonsOidcClientWithLoginBeans.java b/spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/client/SpringAddonsOidcClientWithLoginBeans.java
index 1dcfc9608..e6a86ec59 100644
--- a/spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/client/SpringAddonsOidcClientWithLoginBeans.java
+++ b/spring-addons-starter-oidc/src/main/java/com/c4_soft/springaddons/security/oidc/starter/synchronised/client/SpringAddonsOidcClientWithLoginBeans.java
@@ -2,7 +2,6 @@
import java.util.ArrayList;
import java.util.Optional;
-
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -27,12 +26,12 @@
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.util.UriComponentsBuilder;
-
import com.c4_soft.springaddons.security.oidc.starter.ClaimSetAuthoritiesConverter;
import com.c4_soft.springaddons.security.oidc.starter.ConfigurableClaimSetAuthoritiesConverter;
import com.c4_soft.springaddons.security.oidc.starter.LogoutRequestUriBuilder;
@@ -48,7 +47,6 @@
import com.c4_soft.springaddons.security.oidc.starter.properties.condition.configuration.IsClientWithLoginCondition;
import com.c4_soft.springaddons.security.oidc.starter.synchronised.ServletConfigurationSupport;
import com.c4_soft.springaddons.security.oidc.starter.synchronised.SpringAddonsOidcBeans;
-
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@@ -56,23 +54,31 @@
/**
* The following {@link ConditionalOnMissingBean @ConditionalOnMissingBeans} are auto-configured
*
- * - springAddonsClientFilterChain: a {@link SecurityFilterChain}. Instantiated only if "com.c4-soft.springaddons.oidc.client.security-matchers" property has
- * at least one entry. If defined, it is with highest precedence, to ensure that all routes defined in this security matcher property are intercepted by this
- * filter-chain.
- * - oAuth2AuthorizationRequestResolver: a {@link OAuth2AuthorizationRequestResolver}. Default instance is a
- * {@link SpringAddonsOAuth2AuthorizationRequestResolver} which sets the client hostname in the redirect URI with
- * {@link SpringAddonsOidcClientProperties#clientUri SpringAddonsOidcClientProperties#client-uri}
- * - logoutRequestUriBuilder: builder for RP-Initiated Logout queries, taking
- * configuration from properties for OIDC providers which do not strictly comply with the spec: logout URI not provided by OIDC conf or non standard parameter
- * names (Auth0 and Cognito are samples of such OPs)
- * - logoutSuccessHandler: a {@link LogoutSuccessHandler}. Default instance is a {@link SpringAddonsLogoutSuccessHandler} which logs a user out from the last
- * authorization server he logged on.
- * - authoritiesConverter: an {@link ClaimSetAuthoritiesConverter}. Default instance is a {@link ConfigurableClaimSetAuthoritiesConverter} which reads
- * spring-addons {@link SpringAddonsOidcProperties}
- * - clientAuthorizePostProcessor: a {@link ClientExpressionInterceptUrlRegistryPostProcessor} post processor to fine tune access control from java
- * configuration. It applies to all routes not listed in "permit-all" property configuration. Default requires users to be authenticated.
- * - clientHttpPostProcessor: a {@link ClientSynchronizedHttpSecurityPostProcessor} to override anything from above auto-configuration. It is called just
- * before the security filter-chain is returned. Default is a no-op.
+ * - springAddonsClientFilterChain: a {@link SecurityFilterChain}. Instantiated only if
+ * "com.c4-soft.springaddons.oidc.client.security-matchers" property has at least one entry. If
+ * defined, it is with highest precedence, to ensure that all routes defined in this security
+ * matcher property are intercepted by this filter-chain.
+ * - oAuth2AuthorizationRequestResolver: a {@link OAuth2AuthorizationRequestResolver}. Default
+ * instance is a {@link SpringAddonsOAuth2AuthorizationRequestResolver} which sets the client
+ * hostname in the redirect URI with {@link SpringAddonsOidcClientProperties#clientUri
+ * SpringAddonsOidcClientProperties#client-uri}
+ * - logoutRequestUriBuilder: builder for
+ * RP-Initiated Logout
+ * queries, taking configuration from properties for OIDC providers which do not strictly comply
+ * with the spec: logout URI not provided by OIDC conf or non standard parameter names (Auth0 and
+ * Cognito are samples of such OPs)
+ * - logoutSuccessHandler: a {@link LogoutSuccessHandler}. Default instance is a
+ * {@link SpringAddonsLogoutSuccessHandler} which logs a user out from the last authorization server
+ * he logged on.
+ * - authoritiesConverter: an {@link ClaimSetAuthoritiesConverter}. Default instance is a
+ * {@link ConfigurableClaimSetAuthoritiesConverter} which reads spring-addons
+ * {@link SpringAddonsOidcProperties}
+ * - clientAuthorizePostProcessor: a {@link ClientExpressionInterceptUrlRegistryPostProcessor}
+ * post processor to fine tune access control from java configuration. It applies to all routes not
+ * listed in "permit-all" property configuration. Default requires users to be authenticated.
+ * - clientHttpPostProcessor: a {@link ClientSynchronizedHttpSecurityPostProcessor} to override
+ * anything from above auto-configuration. It is called just before the security filter-chain is
+ * returned. Default is a no-op.
*
*
* @author Jerome Wacongne ch4mp@c4-soft.com
@@ -85,64 +91,74 @@
@Slf4j
public class SpringAddonsOidcClientWithLoginBeans {
- /**
- *
- * Instantiated only if "com.c4-soft.springaddons.oidc.client.security-matchers" property has at least one entry. If defined, it is with higher precedence
- * than resource server one.
- *
- * It defines:
- *
- * - If the path to login page was provided in conf, a @Controller must be provided to handle it. Otherwise Spring Boot default generated one is used
- * (be aware that it does not work when bound to 80 or 8080 with SSL enabled, so, in that case, use another port or define a login path and a controller to
- * handle it)
- * - logout (using {@link SpringAddonsLogoutSuccessHandler} by default)
- * - forces SSL usage if it is enabled
properties
- * - CSRF protection as defined in spring-addons client properties (enabled by default in this filter-chain).
- * - allow access to unauthorized requests to path matchers listed in spring-security client "permit-all" property
- * - as usual, apply {@link ClientExpressionInterceptUrlRegistryPostProcessor} for access control configuration from Java conf and
- * {@link ClientSynchronizedHttpSecurityPostProcessor} to override anything from the auto-configuration listed above
- *
- *
- * @param http the security filter-chain builder to configure
- * @param serverProperties Spring Boot standard server properties
- * @param authorizationRequestResolver the authorization request resolver to use. By default {@link SpringAddonsOAuth2AuthorizationRequestResolver} (adds
- * authorization request parameters defined in properties and builds absolutes callback URI)
- * @param preAuthorizationCodeRedirectStrategy the redirection strategy to use for authorization-code request
- * @param authenticationEntryPoint the {@link AuthenticationEntryPoint} to use. Default is {@link SpringAddonsAuthenticationEntryPoint}
- * @param authenticationSuccessHandler the authentication success handler to use. Default is a {@link SpringAddonsOauth2AuthenticationSuccessHandler}
- * @param authenticationFailureHandler the authentication failure handler to use. Default is a {@link SpringAddonsOauth2AuthenticationFailureHandler}
- * @param invalidSessionStrategy default redirects to login, unless another status is set in
- * com.c4-soft.springaddons.oidc.client.oauth2-redirections.invalid-session-strategy
- * @param logoutSuccessHandler Defaulted to {@link SpringAddonsLogoutSuccessHandler} which can handle "almost" RP Initiated Logout conformant OPs (like
- * Auth0 and Cognito). Default is a {@link SpringAddonsLogoutSuccessHandler}
- * @param addonsProperties {@link SpringAddonsOAuth2ClientProperties spring-addons client properties}
- * @param authorizePostProcessor post process authorization after "permit-all" configuration was applied (default is "isAuthenticated()" to everything that
- * was not matched)
- * @param httpPostProcessor post process the "http" builder just before it is returned (enables to override anything from the auto-configuration)
- * spring-addons client properties}
- * @param oidcBackChannelLogoutHandler if present, Back-Channel Logout is enabled. A default {@link OidcBackChannelLogoutHandler} is provided if
- * com.c4-soft.springaddons.oidc.client.back-channel-logout.enabled is true
- * @return a security filter-chain scoped to specified security-matchers and adapted to OAuth2 clients
- * @throws Exception in case of miss-configuration
- */
- @Order(Ordered.LOWEST_PRECEDENCE - 1)
- @Bean
- SecurityFilterChain springAddonsClientFilterChain(
- HttpSecurity http,
- ServerProperties serverProperties,
- PreAuthorizationCodeRedirectStrategy preAuthorizationCodeRedirectStrategy,
- OAuth2AuthorizationRequestResolver authorizationRequestResolver,
- AuthenticationEntryPoint authenticationEntryPoint,
- AuthenticationSuccessHandler authenticationSuccessHandler,
- AuthenticationFailureHandler authenticationFailureHandler,
- InvalidSessionStrategy invalidSessionStrategy,
- LogoutSuccessHandler logoutSuccessHandler,
- SpringAddonsOidcProperties addonsProperties,
- ClientExpressionInterceptUrlRegistryPostProcessor authorizePostProcessor,
- ClientSynchronizedHttpSecurityPostProcessor httpPostProcessor,
- Optional oidcBackChannelLogoutHandler)
- throws Exception {
- // @formatter:off
+ /**
+ *
+ * Instantiated only if "com.c4-soft.springaddons.oidc.client.security-matchers" property has at
+ * least one entry. If defined, it is with higher precedence than resource server one.
+ *
+ * It defines:
+ *
+ * - If the path to login page was provided in conf, a @Controller must be provided to
+ * handle it. Otherwise Spring Boot default generated one is used (be aware that it does not work
+ * when bound to 80 or 8080 with SSL enabled, so, in that case, use another port or define a login
+ * path and a controller to handle it)
+ * - logout (using {@link SpringAddonsLogoutSuccessHandler} by default)
+ * - forces SSL usage if it is enabled
properties
+ * - CSRF protection as defined in spring-addons client properties (enabled by default in
+ * this filter-chain).
+ * - allow access to unauthorized requests to path matchers listed in spring-security
+ * client "permit-all" property
+ * - as usual, apply {@link ClientExpressionInterceptUrlRegistryPostProcessor} for access
+ * control configuration from Java conf and {@link ClientSynchronizedHttpSecurityPostProcessor} to
+ * override anything from the auto-configuration listed above
+ *
+ *
+ * @param http the security filter-chain builder to configure
+ * @param serverProperties Spring Boot standard server properties
+ * @param authorizationRequestResolver the authorization request resolver to use. By default
+ * {@link SpringAddonsOAuth2AuthorizationRequestResolver} (adds authorization request
+ * parameters defined in properties and builds absolutes callback URI)
+ * @param preAuthorizationCodeRedirectStrategy the redirection strategy to use for
+ * authorization-code request
+ * @param authenticationEntryPoint the {@link AuthenticationEntryPoint} to use. Default is
+ * {@link SpringAddonsAuthenticationEntryPoint}
+ * @param authenticationSuccessHandler the authentication success handler to use. Default is a
+ * {@link SpringAddonsOauth2AuthenticationSuccessHandler}
+ * @param authenticationFailureHandler the authentication failure handler to use. Default is a
+ * {@link SpringAddonsOauth2AuthenticationFailureHandler}
+ * @param invalidSessionStrategy default redirects to login, unless another status is set in
+ * com.c4-soft.springaddons.oidc.client.oauth2-redirections.invalid-session-strategy
+ * @param logoutSuccessHandler Defaulted to {@link SpringAddonsLogoutSuccessHandler} which can
+ * handle "almost" RP Initiated Logout conformant OPs (like Auth0 and Cognito). Default is
+ * a {@link SpringAddonsLogoutSuccessHandler}
+ * @param addonsProperties {@link SpringAddonsOAuth2ClientProperties spring-addons client
+ * properties}
+ * @param authorizePostProcessor post process authorization after "permit-all" configuration was
+ * applied (default is "isAuthenticated()" to everything that was not matched)
+ * @param httpPostProcessor post process the "http" builder just before it is returned (enables to
+ * override anything from the auto-configuration) spring-addons client properties}
+ * @param oidcBackChannelLogoutHandler if present, Back-Channel Logout is enabled. A default
+ * {@link OidcBackChannelLogoutHandler} is provided if
+ * com.c4-soft.springaddons.oidc.client.back-channel-logout.enabled is true
+ * @return a security filter-chain scoped to specified security-matchers and adapted to OAuth2
+ * clients
+ * @throws Exception in case of miss-configuration
+ */
+ @Order(Ordered.LOWEST_PRECEDENCE - 1)
+ @Bean
+ SecurityFilterChain springAddonsClientFilterChain(HttpSecurity http,
+ ServerProperties serverProperties,
+ PreAuthorizationCodeRedirectStrategy preAuthorizationCodeRedirectStrategy,
+ OAuth2AuthorizationRequestResolver authorizationRequestResolver,
+ AuthenticationEntryPoint authenticationEntryPoint,
+ AuthenticationSuccessHandler authenticationSuccessHandler,
+ AuthenticationFailureHandler authenticationFailureHandler,
+ InvalidSessionStrategy invalidSessionStrategy, Optional logoutHandler,
+ LogoutSuccessHandler logoutSuccessHandler, SpringAddonsOidcProperties addonsProperties,
+ ClientExpressionInterceptUrlRegistryPostProcessor authorizePostProcessor,
+ ClientSynchronizedHttpSecurityPostProcessor httpPostProcessor,
+ Optional oidcBackChannelLogoutHandler) throws Exception {
+ // @formatter:off
log.info("Applying client OAuth2 configuration for: {}", addonsProperties.getClient().getSecurityMatchers());
http.securityMatcher(addonsProperties.getClient().getSecurityMatchers().toArray(new String[] {}));
@@ -168,181 +184,191 @@ SecurityFilterChain springAddonsClientFilterChain(
});
// @formatter:on
- if (oidcBackChannelLogoutHandler.isPresent()) {
- http.oidcLogout(ol -> ol.backChannel(bc -> bc.logoutHandler(oidcBackChannelLogoutHandler.get())));
- }
+ if (oidcBackChannelLogoutHandler.isPresent()) {
+ http.oidcLogout(
+ ol -> ol.backChannel(bc -> bc.logoutHandler(oidcBackChannelLogoutHandler.get())));
+ }
- ServletConfigurationSupport.configureClient(http, serverProperties, addonsProperties, authorizePostProcessor, httpPostProcessor);
+ ServletConfigurationSupport.configureClient(http, serverProperties, addonsProperties,
+ authorizePostProcessor, httpPostProcessor);
- return http.build();
- }
+ return http.build();
+ }
- /**
- * Use a {@link SpringAddonsOAuth2AuthorizationRequestResolver} which:
- *
- * - takes hostname and port from configuration properties (and works even if SSL is enabled on port 8080)
- * - spport defining additionl authorization request parameters from properties
- *
- *
- * @param bootClientProperties "standard" Spring Boot OAuth2 client properties
- * @param clientRegistrationRepository
- * @param addonsProperties "spring-addons" OAuth2 client properties
- * @return {@link SpringAddonsOAuth2AuthorizationRequestResolver}
- */
- @ConditionalOnMissingBean
- @Bean
- OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver(
- OAuth2ClientProperties bootClientProperties,
- ClientRegistrationRepository clientRegistrationRepository,
- SpringAddonsOidcProperties addonsProperties) {
- return new SpringAddonsOAuth2AuthorizationRequestResolver(bootClientProperties, clientRegistrationRepository, addonsProperties.getClient());
- }
+ /**
+ * Use a {@link SpringAddonsOAuth2AuthorizationRequestResolver} which:
+ *
+ * - takes hostname and port from configuration properties (and works even if SSL is enabled on
+ * port 8080)
+ * - spport defining additionl authorization request parameters from properties
+ *
+ *
+ * @param bootClientProperties "standard" Spring Boot OAuth2 client properties
+ * @param clientRegistrationRepository
+ * @param addonsProperties "spring-addons" OAuth2 client properties
+ * @return {@link SpringAddonsOAuth2AuthorizationRequestResolver}
+ */
+ @ConditionalOnMissingBean
+ @Bean
+ OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver(
+ OAuth2ClientProperties bootClientProperties,
+ ClientRegistrationRepository clientRegistrationRepository,
+ SpringAddonsOidcProperties addonsProperties) {
+ return new SpringAddonsOAuth2AuthorizationRequestResolver(bootClientProperties,
+ clientRegistrationRepository, addonsProperties.getClient());
+ }
- /**
- * Build logout request for RP-Initiated Logout. It works with most OIDC
- * provider: those complying with the spec (Keycloak for instance), off course, but also those which are close enough to it (Auth0, Cognito, ...)
- *
- * @param addonsProperties {@link SpringAddonsOAuth2ClientProperties} to pick logout configuration for divergence to the standard (logout URI not provided
- * in .well-known/openid-configuration and non-conform parameter names)
- * @return {@link SpringAddonsOAuth2LogoutRequestUriBuilder]
- */
- @ConditionalOnMissingBean
- @Bean
- LogoutRequestUriBuilder logoutRequestUriBuilder(SpringAddonsOidcProperties addonsProperties) {
- return new SpringAddonsOAuth2LogoutRequestUriBuilder(addonsProperties.getClient());
- }
+ /**
+ * Build logout request for
+ * RP-Initiated
+ * Logout. It works with most OIDC provider: those complying with the spec (Keycloak for
+ * instance), off course, but also those which are close enough to it (Auth0, Cognito, ...)
+ *
+ * @param addonsProperties {@link SpringAddonsOAuth2ClientProperties} to pick logout configuration
+ * for divergence to the standard (logout URI not provided in
+ * .well-known/openid-configuration and non-conform parameter names)
+ * @return {@link SpringAddonsOAuth2LogoutRequestUriBuilder]
+ */
+ @ConditionalOnMissingBean
+ @Bean
+ LogoutRequestUriBuilder logoutRequestUriBuilder(SpringAddonsOidcProperties addonsProperties) {
+ return new SpringAddonsOAuth2LogoutRequestUriBuilder(addonsProperties.getClient());
+ }
- /**
- * Single tenant logout handler for OIDC provider complying to RP-Initiated
- * Logout (or approximately complying to it like Auth0 or Cognito)
- *
- * @param logoutRequestUriBuilder delegate doing the smart job
- * @param clientRegistrationRepository
- * @param addonsProperties
- * @return {@link SpringAddonsLogoutSuccessHandler}
- */
- @ConditionalOnMissingBean
- @Bean
- LogoutSuccessHandler logoutSuccessHandler(
- LogoutRequestUriBuilder logoutRequestUriBuilder,
- ClientRegistrationRepository clientRegistrationRepository,
- SpringAddonsOidcProperties addonsProperties) {
- return new SpringAddonsLogoutSuccessHandler(logoutRequestUriBuilder, clientRegistrationRepository, addonsProperties);
- }
+ /**
+ * Single tenant logout handler for OIDC provider complying to
+ * RP-Initiated Logout
+ * (or approximately complying to it like Auth0 or Cognito)
+ *
+ * @param logoutRequestUriBuilder delegate doing the smart job
+ * @param clientRegistrationRepository
+ * @param addonsProperties
+ * @return {@link SpringAddonsLogoutSuccessHandler}
+ */
+ @ConditionalOnMissingBean
+ @Bean
+ LogoutSuccessHandler logoutSuccessHandler(LogoutRequestUriBuilder logoutRequestUriBuilder,
+ ClientRegistrationRepository clientRegistrationRepository,
+ SpringAddonsOidcProperties addonsProperties) {
+ return new SpringAddonsLogoutSuccessHandler(logoutRequestUriBuilder,
+ clientRegistrationRepository, addonsProperties);
+ }
- /**
- * @return a Post processor for access control in Java configuration which requires users to be authenticated. It is called after "permit-all" configuration
- * property was applied.
- */
- @ConditionalOnMissingBean
- @Bean
- ClientExpressionInterceptUrlRegistryPostProcessor clientAuthorizePostProcessor() {
- return registry -> registry.anyRequest().authenticated();
- }
+ /**
+ * @return a Post processor for access control in Java configuration which requires users to be
+ * authenticated. It is called after "permit-all" configuration property was applied.
+ */
+ @ConditionalOnMissingBean
+ @Bean
+ ClientExpressionInterceptUrlRegistryPostProcessor clientAuthorizePostProcessor() {
+ return registry -> registry.anyRequest().authenticated();
+ }
- /**
- * @return a no-op post processor
- */
- @ConditionalOnMissingBean
- @Bean
- ClientSynchronizedHttpSecurityPostProcessor clientHttpPostProcessor() {
- return http -> http;
- }
+ /**
+ * @return a no-op post processor
+ */
+ @ConditionalOnMissingBean
+ @Bean
+ ClientSynchronizedHttpSecurityPostProcessor clientHttpPostProcessor() {
+ return http -> http;
+ }
- @ConditionalOnMissingBean
- @Bean
- PreAuthorizationCodeRedirectStrategy authorizationCodeRedirectStrategy(SpringAddonsOidcProperties addonsProperties) {
- return new SpringAddonsPreAuthorizationCodeRedirectStrategy(addonsProperties.getClient().getOauth2Redirections().getPreAuthorizationCode());
- }
+ @ConditionalOnMissingBean
+ @Bean
+ PreAuthorizationCodeRedirectStrategy authorizationCodeRedirectStrategy(
+ SpringAddonsOidcProperties addonsProperties) {
+ return new SpringAddonsPreAuthorizationCodeRedirectStrategy(
+ addonsProperties.getClient().getOauth2Redirections().getPreAuthorizationCode());
+ }
- public static class SpringAddonsPreAuthorizationCodeRedirectStrategy extends SpringAddonsOauth2RedirectStrategy
- implements
- PreAuthorizationCodeRedirectStrategy {
- public SpringAddonsPreAuthorizationCodeRedirectStrategy(HttpStatus defaultStatus) {
- super(defaultStatus);
- }
+ public static class SpringAddonsPreAuthorizationCodeRedirectStrategy
+ extends SpringAddonsOauth2RedirectStrategy implements PreAuthorizationCodeRedirectStrategy {
+ public SpringAddonsPreAuthorizationCodeRedirectStrategy(HttpStatus defaultStatus) {
+ super(defaultStatus);
}
+ }
- @ConditionalOnMissingBean(InvalidSessionStrategy.class)
- @Bean
- InvalidSessionStrategy invalidSessionStrategy(SpringAddonsOidcProperties addonsProperties) {
- final var location = addonsProperties
- .getClient()
- .getLoginUri()
- .orElse(
- UriComponentsBuilder
- .fromUri(addonsProperties.getClient().getClientUri())
- .pathSegment(addonsProperties.getClient().getClientUri().getPath(), "/login")
- .build()
- .toUri())
- .toString();
- log
- .debug(
- "Invalid session. Returning %d and request authentication at %s"
- .formatted(addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy().value(), location));
-
- if (addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy() == HttpStatus.FOUND) {
- return new SimpleRedirectInvalidSessionStrategy(location);
- }
+ @ConditionalOnMissingBean(InvalidSessionStrategy.class)
+ @Bean
+ InvalidSessionStrategy invalidSessionStrategy(SpringAddonsOidcProperties addonsProperties) {
+ final var location = addonsProperties.getClient().getLoginUri()
+ .orElse(UriComponentsBuilder.fromUri(addonsProperties.getClient().getClientUri())
+ .pathSegment(addonsProperties.getClient().getClientUri().getPath(), "/login").build()
+ .toUri())
+ .toString();
+ log.debug("Invalid session. Returning %d and request authentication at %s".formatted(
+ addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy().value(),
+ location));
- return (HttpServletRequest request, HttpServletResponse response) -> {
- response.setStatus(addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy().value());
- response.setHeader(HttpHeaders.LOCATION, location);
- if (addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy().is4xxClientError() || addonsProperties
- .getClient()
- .getOauth2Redirections()
- .getInvalidSessionStrategy()
- .is5xxServerError()) {
- response.getOutputStream().write("Invalid session. Please authenticate at %s".formatted(location).getBytes());
- }
- response.flushBuffer();
- };
+ if (addonsProperties.getClient().getOauth2Redirections()
+ .getInvalidSessionStrategy() == HttpStatus.FOUND) {
+ return new SimpleRedirectInvalidSessionStrategy(location);
}
- @Conditional(DefaultAuthenticationEntryPointCondition.class)
- @Bean
- AuthenticationEntryPoint authenticationEntryPoint(SpringAddonsOidcProperties addonsProperties) {
- return new SpringAddonsAuthenticationEntryPoint(addonsProperties.getClient());
- }
+ return (HttpServletRequest request, HttpServletResponse response) -> {
+ response.setStatus(
+ addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy().value());
+ response.setHeader(HttpHeaders.LOCATION, location);
+ if (addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy()
+ .is4xxClientError()
+ || addonsProperties.getClient().getOauth2Redirections().getInvalidSessionStrategy()
+ .is5xxServerError()) {
+ response.getOutputStream()
+ .write("Invalid session. Please authenticate at %s".formatted(location).getBytes());
+ }
+ response.flushBuffer();
+ };
+ }
- @Conditional(DefaultAuthenticationSuccessHandlerCondition.class)
- @Bean
- AuthenticationSuccessHandler authenticationSuccessHandler(SpringAddonsOidcProperties addonsProperties) {
- return new SpringAddonsOauth2AuthenticationSuccessHandler(addonsProperties);
- }
+ @Conditional(DefaultAuthenticationEntryPointCondition.class)
+ @Bean
+ AuthenticationEntryPoint authenticationEntryPoint(SpringAddonsOidcProperties addonsProperties) {
+ return new SpringAddonsAuthenticationEntryPoint(addonsProperties.getClient());
+ }
- @Conditional(DefaultAuthenticationFailureHandlerCondition.class)
- @Bean
- AuthenticationFailureHandler authenticationFailureHandler(SpringAddonsOidcProperties addonsProperties) {
- return new SpringAddonsOauth2AuthenticationFailureHandler(addonsProperties);
- }
+ @Conditional(DefaultAuthenticationSuccessHandlerCondition.class)
+ @Bean
+ AuthenticationSuccessHandler authenticationSuccessHandler(
+ SpringAddonsOidcProperties addonsProperties) {
+ return new SpringAddonsOauth2AuthenticationSuccessHandler(addonsProperties);
+ }
- /**
- * FIXME: use only the new CORS properties at next major release
- */
- @Conditional(DefaultCorsFilterCondition.class)
- @Bean
- CorsFilter corsFilter(SpringAddonsOidcProperties addonsProperties) {
- final var corsProps = new ArrayList<>(addonsProperties.getCors());
- final var deprecatedClientCorsProps = addonsProperties.getClient().getCors();
- corsProps.addAll(deprecatedClientCorsProps);
+ @Conditional(DefaultAuthenticationFailureHandlerCondition.class)
+ @Bean
+ AuthenticationFailureHandler authenticationFailureHandler(
+ SpringAddonsOidcProperties addonsProperties) {
+ return new SpringAddonsOauth2AuthenticationFailureHandler(addonsProperties);
+ }
- return ServletConfigurationSupport.getCorsFilterBean(corsProps);
- }
+ /**
+ * FIXME: use only the new CORS properties at next major release
+ */
+ @Conditional(DefaultCorsFilterCondition.class)
+ @Bean
+ CorsFilter corsFilter(SpringAddonsOidcProperties addonsProperties) {
+ final var corsProps = new ArrayList<>(addonsProperties.getCors());
+ final var deprecatedClientCorsProps = addonsProperties.getClient().getCors();
+ corsProps.addAll(deprecatedClientCorsProps);
- @Conditional(DefaultOidcSessionRegistryCondition.class)
- @Bean
- OidcSessionRegistry oidcSessionRegistry() {
- return new InMemoryOidcSessionRegistry();
- }
+ return ServletConfigurationSupport.getCorsFilterBean(corsProps);
+ }
- @Conditional(DefaultOidcBackChannelLogoutHandlerCondition.class)
- @Bean
- OidcBackChannelLogoutHandler oidcBackChannelLogoutHandler(OidcSessionRegistry sessionRegistry, SpringAddonsOidcProperties addonsProperties) {
- OidcBackChannelLogoutHandler logoutHandler = new OidcBackChannelLogoutHandler(sessionRegistry);
- addonsProperties.getClient().getBackChannelLogout().getInternalLogoutUri().ifPresent(logoutHandler::setLogoutUri);
- addonsProperties.getClient().getBackChannelLogout().getCookieName().ifPresent(logoutHandler::setSessionCookieName);
- return logoutHandler;
- }
+ @Conditional(DefaultOidcSessionRegistryCondition.class)
+ @Bean
+ OidcSessionRegistry oidcSessionRegistry() {
+ return new InMemoryOidcSessionRegistry();
+ }
+
+ @Conditional(DefaultOidcBackChannelLogoutHandlerCondition.class)
+ @Bean
+ OidcBackChannelLogoutHandler oidcBackChannelLogoutHandler(OidcSessionRegistry sessionRegistry,
+ SpringAddonsOidcProperties addonsProperties) {
+ OidcBackChannelLogoutHandler logoutHandler = new OidcBackChannelLogoutHandler(sessionRegistry);
+ addonsProperties.getClient().getBackChannelLogout().getInternalLogoutUri()
+ .ifPresent(logoutHandler::setLogoutUri);
+ addonsProperties.getClient().getBackChannelLogout().getCookieName()
+ .ifPresent(logoutHandler::setSessionCookieName);
+ return logoutHandler;
+ }
}