spring-projects / spring-projects/spring-security

404 Errors for SP Metadata and IDP Initiated Login

Open
#14,514 13 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: saml2 status: feedback-provided type: bug
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

I'm currently upgrading an existing application from spring-security-saml2-core 1.0.10.RELEASE (which has reached end-of-life) to spring-security-saml2-service-provider 5.6.9. As these versions have significant differences, I started by creating a sample Spring application based on the example provided at this GitHub repository. This test application worked correctly, allowing both IDP-initiated logins and the successful download of SP metadata using the URL http://{host-name}/saml2/service-provider-metadata/{registration-id}.

However, after integrating similar changes into my actual project, I'm encountering issues. Here's a brief overview of what I did:

Code Addition: I wrote a class (similar to the one in the sample application) in my codebase.


// Necessary Imports

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private ResourceLoader resourceLoader = new DefaultResourceLoader();


    @Autowired(required = false)
    private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        LOG.info("In the configure method");
        if (isSAMLEnabled()) {
            LOG.info("Inside IF");
            http
                    .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .saml2Login(); 

            Converter<HttpServletRequest, RelyingPartyRegistration> relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver(relyingPartyRegistrationRepository);
            Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
            http.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class);
        }


        LOG.info("Configure method done.");
    }

    @Bean
    public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() {

        LOG.info("Inside the bean method");
        if (isSAMLEnabled()) {
            return createRelyingPartyRegistrationRepository();
        } else {
            return null;
        }
    }

    private RelyingPartyRegistrationRepository createRelyingPartyRegistrationRepository() {

        LOG.info("Inside Repo method");


        String entityId = //Appropriate Value
        String ssoUrl = //Appropriate Value
        String certificatePath = //Appropriate Value

        try {
            Resource resource = resourceLoader.getResource(certificatePath);
            InputStream inputStream = resource.getInputStream();
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate certificate = (X509Certificate) cf.generateCertificate(inputStream);
            Saml2X509Credential credential = Saml2X509Credential.verification(certificate);

            RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration
                    .withRegistrationId("okta-idp")
                    .assertingPartyDetails(party -> party
                            .entityId(entityId)
                            .singleSignOnServiceLocation(ssoUrl)
                            .wantAuthnRequestsSigned(false)
                            .verificationX509Credentials(c -> c.add(credential))
                    ).build();

            LOG.info("repo method successful");
            return new InMemoryRelyingPartyRegistrationRepository(relyingPartyRegistration);

        } catch (Exception e) {
            LOG.info("Failed in repo method");
            throw new RuntimeException("Error configuring SAML ", e);
        }
    }

    private boolean isSAMLEnabled() {
        LOG.info("Checking if SAML is enabled...");
        // Logic to check if SAML is enabled, this part works fine.
    }
}

Observation in Logs: Upon restarting my server, the logs indicate that the relyingParty instance is being set up correctly.

2024-01-29 11:36:08,200 INFO Inside the bean method
2024-01-29 11:36:08,200 INFO Checking if SAML is enabled...
2024-01-29 11:36:08,200 INFO Inside Repo method
2024-01-29 11:36:08,212 INFO repo method successful
2024-01-29 11:36:08,324 INFO In the configure method
2024-01-29 11:36:08,324 INFO Checking if SAML is enabled...
2024-01-29 11:36:08,324 INFO Inside IF
2024-01-29 11:36:08,980 INFO Configure method done.

Issue Encountered: Despite the logs suggesting correct setup, accessing http://{host-name}/saml2/service-provider-metadata/{registration-id} results in a 404 Error. Similarly, I'm also receiving a 404 Error when attempting an IDP-initiated login.

HTTP ERROR 404 Not Found
URI: /saml2/service-provider-metadata/{registartion-id}
STATUS:  404
MESSAGE: Not Found
SERVLET: default

I am puzzled as to what could be causing these issues. It seems like my setup should work as it's based on a working example. Has anyone faced similar problems when upgrading to spring-security-saml2-service-provider 5.6.9? Any insights or suggestions on what might be going wrong or what I should check?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the SecurityConfig class shown in the issue, especially the relyingPartyRegistrationRepository bean, saml2Login configuration, and manually added Saml2MetadataFilter. Compare that configuration with the linked sample application and verify the registration ID and mappings for the metadata and IDP-initiated login URLs. Done means both URLs resolve successfully in the upgraded application rather than returning 404.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring, spring-boot
Domain
authentication, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.