Port in logout URL is not customizable in OIDC back channel logout handler
Describe the bug
In Spring Security 6.2.2 the OidcBackChannelLogoutHandler.java logout handler automatically replaces the logout URL endpoint hostname with localhost. However, in a Tomcat context, we also need to specify the port number, typically 8080. This is not possible in the current implementation.
To Reproduce Initiate a back channel logout.
Expected behavior
Local session is invalidated through a POST request to http://localhost:<PORT>/logout, where in my case it should be http://localhost:8080/logout.
Actual behavior
A logout POST request is send to http://localhost/logout, with no effect.
String computeLogoutEndpoint(HttpServletRequest request) {
String url = request.getRequestURL().toString();
return UriComponentsBuilder.fromHttpUrl(url)
.host("localhost")
.replacePath(this.logoutEndpointName)
.build()
.toUriString();
}
Sample This is my security config setup:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, AccessDeniedHandler accessDeniedHandler,
AuthenticationEntryPoint authenticationEntryPoint,
GrantedAuthoritiesMapper grantedAuthoritiesMapper,
AuthenticationSuccessHandler authenticationSuccessHandler,
LogoutSuccessHandler logoutSuccessHandler,
ClientRegistrationRepository clientRegistrationRepository,
MvcRequestMatcher.Builder mvc,
OidcSessionRegistry oidcSessionRegistry) throws Exception {
return http
.csrf(csrf -> csrf.disable()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
)
.addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class)
.authorizeHttpRequests(authorize -> authorize
...
.anyRequest().authenticated()
)
.oauth2Login(oauth2 -> oauth2
.authorizationEndpoint(authorizationEndpointConfig -> {
var resolver = new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository, OAUTH2_REQUEST_BASE_URI);
resolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());
authorizationEndpointConfig.authorizationRequestResolver(resolver);
})
.userInfoEndpoint(userInfo -> userInfo
.userAuthoritiesMapper(grantedAuthoritiesMapper))
.successHandler(authenticationSuccessHandler)
.oidcSessionRegistry(oidcSessionRegistry)
)
.logout(logout -> logout
.logoutSuccessHandler(logoutSuccessHandler)
)
.oidcLogout(oidcLogout -> oidcLogout
.backChannel(withDefaults())
.clientRegistrationRepository(clientRegistrationRepository)
.oidcSessionRegistry(oidcSessionRegistry)
)
...
.build();
}
Hi, @aelillie, thanks for the report. I'm not sure I understand completely just yet, though. The code you outlined does not remove any port from the resulting URI (see also) so it seems like I might be missing some details to be able to apply the appropriate fix.
Can you provide a minimum reproducer that demonstrates the issue you are having?
Hi @jzheaux , thank you for your quick respond. That is true, but the issue is that I do not have the possibility to add one.
If the request URL is e.g. http://server-one.com/logout/connect/back-channel/kc, the resulting logout URL will be http://localhost/logout.
Thanks for the feedback, @aelillie. I'll close this in favor of #14609, the fix should go out in the next maintenance release.