spring-security icon indicating copy to clipboard operation
spring-security copied to clipboard

Port in logout URL is not customizable in OIDC back channel logout handler

Open aelillie opened this issue 1 year ago • 2 comments

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

aelillie avatar Mar 04 '24 12:03 aelillie

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?

jzheaux avatar Mar 04 '24 17:03 jzheaux

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.

aelillie avatar Mar 05 '24 07:03 aelillie

Thanks for the feedback, @aelillie. I'll close this in favor of #14609, the fix should go out in the next maintenance release.

jzheaux avatar Mar 22 '24 22:03 jzheaux