Search code examples
springspring-bootspring-securityspring-samlspring-security-saml2

Unable to change default "reply Url" (assertion consumer service Location) in Spring security SAML SSO


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"


Solution

  • Looking around in the source code I found the solution.

    It turns out you have to update "Reply URL" link in 2 places

    1. In 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.

    1. In 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}