spring-projects / spring-security

Spring Security
http://spring.io/projects/spring-security
Apache License 2.0
8.55k stars 5.79k forks source link

401 on SAML logout if asserting party does not support SLO #15122

Open OrangeDog opened 1 month ago

OrangeDog commented 1 month ago

Describe the bug When I POST to the SAML logoutUrl, a 401 response is returned.

To Reproduce

.logout(logout -> logout.invalidateHttpSession(false))  // issue #14853
.saml2Login(saml -> saml
    .authenticationRequestUri("/saml/authenticate/{registrationId}")
    .loginPage("/saml/discovery")
    .loginProcessingUrl("/saml/SSO")
)
.saml2Logout(saml -> saml
    .logoutUrl("/saml/logout")
    .logoutRequest(request -> request.logoutUrl("/saml/SingleLogout"))
    .logoutResponse(response -> response.logoutUrl("/saml/SingleLogout"))
)
14:15:21.139 [XNIO-1 task-2] DEBUG FilterChainProxy - Securing POST /saml/logout
14:15:21.144 [XNIO-1 task-2] DEBUG HttpSessionSecurityContextRepository - Retrieved SecurityContextImpl [Authentication=Saml2Authentication [Principal=User(...), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=d39d3aab-9fa4-47e1-9e08-f83036c405e8], Granted Authorities=[ROLE_USER, ROLE_ADMIN]]]
14:15:21.144 [XNIO-1 task-2] DEBUG SecurityContextPersistenceFilter - Set SecurityContextHolder to SecurityContextImpl [Authentication=Saml2Authentication [Principal=User(...), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=d39d3aab-9fa4-47e1-9e08-f83036c405e8], Granted Authorities=[ROLE_USER, ROLE_ADMIN]]]
14:15:21.144 [XNIO-1 task-2] DEBUG Saml2LogoutConfigurer$Saml2RelyingPartyInitiatedLogoutFilter - Logging out [Saml2Authentication [Principal=User(...), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=d39d3aab-9fa4-47e1-9e08-f83036c405e8], Granted Authorities=[ROLE_USER, ROLE_ADMIN]]]
14:15:21.144 [XNIO-1 task-2] DEBUG HttpSessionSecurityContextRepository - Did not store empty SecurityContext
14:15:21.145 [XNIO-1 task-2] TRACE OpenSamlLogoutRequestResolver - Attempting to resolve registrationId from Saml2Authentication [Principal=User(...), Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=d39d3aab-9fa4-47e1-9e08-f83036c405e8], Granted Authorities=[ROLE_USER, ROLE_ADMIN]]
14:15:21.146 [XNIO-1 task-2] TRACE Saml2RelyingPartyInitiatedLogoutSuccessHandler - Returning 401 since no logout request generated
14:15:21.147 [XNIO-1 task-2] DEBUG HttpSessionSecurityContextRepository - Did not store empty SecurityContext
14:15:21.147 [XNIO-1 task-2] DEBUG SecurityContextPersistenceFilter - Cleared SecurityContextHolder to complete request

Expected behavior It should redirect to / after logout, regardless of whether the asserting party was sent an SLO request.

Additional The OpenSamlLogoutRequestResolver returned null here:

if (registration.getAssertingPartyDetails().getSingleLogoutServiceLocation() == null) {
    return null;
}

I'm guessing the intent is that the 401 triggers a redirect back to /login, but it should use the same mechanism as the regular logout in case someone is not using the default configuration.