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

Spring Security SAML2 Logout not working with Spring Session Data MongoDB

Open mmoussa-mapfre opened this issue 3 years ago • 5 comments

Describe the bug Spring Security SAML2 Logout is not working with Spring Session Data MongoDB. Our setup fully works if I use in-memory sessions instead of MongoDB sessions.

SP Initiated Logout ends with the app not able to find the Logout Request, it appears to be looking at local session instead of MongoDB. Saml2LogoutResponseFilter Line 107

IDP Initiated Logout ends with the app not able to find the Authentication, again it appears to be looking at local session instead of MongoDB. Saml2LogoutRequestFilter Line 114

To Reproduce I started with Spring's provided Sample SAML2 App and added Spring Session Data MongoDB. Our IDP is ADFS and everything on the IDP side seems standard and correct.

Here are our dependencies - build.gradle file

We deployed using WAR file on Tomcat. JDK 8, OpenSaml 3 ` springCloudVersion=2021.0.3 springBootVersion=2.7.0

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.security:spring-security-saml2-service-provider'
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
implementation 'org.springframework.session:spring-session-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')

`

Security config

`

	http
		.authorizeHttpRequests(authorize -> authorize
			.requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)).permitAll()
			.anyRequest().authenticated()
		)
		.saml2Login(saml2 -> saml2
				.failureUrl(appBaseUrl + "/error"))
		.saml2Logout(Customizer.withDefaults())
		.exceptionHandling(exceptions -> exceptions
				.authenticationEntryPoint(authEntryPoint()))
		.logout(logout -> logout
				.logoutSuccessUrl(appBaseUrl))
		.csrf()
			.csrfTokenRepository(getCsrfTokenRepository())
		.and()
        .headers()
        	.contentSecurityPolicy("default-src 'none';");

` Using this entry point to change /user behavior and remove /login and /logout UIs

`

private DelegatingAuthenticationEntryPoint authEntryPoint() {
	LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = new LinkedHashMap<>();
	entryPoints.put(new AntPathRequestMatcher("/user"), new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));

	DelegatingAuthenticationEntryPoint loginEntryPoint = new DelegatingAuthenticationEntryPoint(entryPoints);
	loginEntryPoint.setDefaultEntryPoint(new LoginUrlAuthenticationEntryPoint("/saml2/authenticate/adfs"));
	return loginEntryPoint;
}

`

Expected behavior Both IDP and SP initiated SAML logouts would use my MongoDB Session store to retrieve the session information.

Single Sign On seems to retrieve the session automatically with MongoDB without any customization. I have the sign on parts working, it is just sign out that is breaking.

Do I have to customize the Logout Validators, Repository, and Filters to get this to work with MongoDB Session?

mmoussa-mapfre avatar Jun 10 '22 14:06 mmoussa-mapfre

Hi, @mmoussa-mapfre. I don't think that Spring Session MongoDB already implements Saml2LogoutRequestRepository, so I believe you will need to implement it yourself and then wire that into the DSL like so:

http
    .saml2Logout((saml2) -> saml2
        .logoutRequest((request) -> request
            .logoutRequestRepository(repository)
        )
    )
    // ...

As for Saml2LogoutRequestFilter, no further configuration should be required, so I may need a sample to make progress. Perhaps what you could do is create a sample and add a test that saves an Authentication to MongoDB and then makes a request to the logout request endpoint.

jzheaux avatar Jun 22 '22 20:06 jzheaux

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues avatar Jun 29 '22 20:06 spring-projects-issues

I thought this was a bug but it appears I will need to implement the repository with MongoDB myself. I don't have time at the moment to work on this so I am closing this issue.

@jzheaux Thank you for the help.

mmoussa-mapfre avatar Jun 29 '22 20:06 mmoussa-mapfre

@jzheaux I am trying to implement this now. I noticed when setting the logoutRequestRepository as you stated, it does not set it on the Saml2RelyingPartyInitiatedLogoutSuccessHandler during creation in Saml2LogoutConfigurer.createSaml2LogoutRequestSuccessHandler(). This might be a bug. How would I change the logoutRequestRepository in the Saml2RelyingPartyInitiatedLogoutSuccessHandler?

mmoussa-mapfre avatar Jul 18 '22 18:07 mmoussa-mapfre

I added a PR to add the logout repository. PR-11618

mmoussa-mapfre avatar Jul 25 '22 17:07 mmoussa-mapfre