I am using spring security Saml 2.0 with spring boot for SSO (Single sign on) with azure as Identity provider.
Spring security uses "{baseUrl}/login/saml2/sso/{registrationId}" as a default "Reply Url",
but I want to use "{baseUrl}/login/{registrationId}"
So following the Official documentation I wrote
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations
.fromMetadataLocation("https://login.microsoftonline.com/<metadata url>")
.registrationId("azure")
.entityId("{baseUrl}")
.assertionConsumerServiceLocation("{baseUrl}/login/{registrationId}")
.build();
By this I get into login page, But after that There is infinite loop of logins...
Spring boot is unable to POST to /login/azure
o.s.security.web.FilterChainProxy : Securing POST /login/azure
s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/login/azure
o.s.s.w.access.AccessDeniedHandlerImpl : Responding with 403 status code
I have tried to allow CSRF for this endpoint and permitAll access, but then It is not able to parse the metadata.
I found that it is implemented in filter "Saml2WebSsoAuthenticationFilter"
Looking around in the source code I found the solution.
It turns out you have to update "Reply URL" link in 2 places
RelyingPartyRegistration
or in application.properties
as I did in question.This will tell Spring where the page will be redirected after successful login, On this URL IP (identity provider) will provide SAML response in XML format.
WebSecurityConfigurerAdapter
So We have to explicitly tell Spring to expect SAML response on this URL and parse it.
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.saml2Login(h -> h.loginProcessingUrl("/login/{registrationId}"));
}
}
This will Update Saml2WebSsoAuthenticationFilter
to use /login/{registrationId}
for SAML parsing instead of /login/saml2/sso/{registrationId}