Search code examples
spring-securityadfs2.0spring-security-saml2

Spring Security Saml2 Response Assertion [_6d73441e-b906-4c63-95be-57cb2f50b030] is missing a subject


With spring security saml2 eventhough I get a saml response i get avalidation error: Assertion [_6d73441e-b906-4c63-95be-57cb2f50b030] is missing a subject However by reading the saml response (from browser's saml tracer) I see that subject exists.

I have used spring security in my project for configuring my app as a service provider with on premises adfs via relying party trust (saml). I have registered the auto spring metadata url while configuring adfs and all seems to work fine. I open a page, get redirected to adfs login page, succesfully login, get a response posted back which seems valid. I'd expect the response to be parsed and to allow access.

My WebSecurityConfig:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
    @Autowired
    private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        OpenSaml4AuthenticationProvider samlProvider = new OpenSaml4AuthenticationProvider();
samlProvider.setAssertionValidator(OpenSaml4AuthenticationProvider.createDefaultAssertionValidator());
samlProvider.setResponseValidator(OpenSaml4AuthenticationProvider.createDefaultResponseValidator());
       
        ProviderManager providerManager = new ProviderManager(
            samlProvider);

        http
            .authorizeRequests(authorize -> authorize
                .antMatchers("/actuator/**",
                    "/",
                    "/favicon.ico",
                    "/saml/**",
                    "/saml2/**",
                    "/login/**").permitAll()
                .anyRequest().authenticated())
            .saml2Login(//Customizer.withDefaults())
                            saml2 -> saml2
                            .authenticationManager(providerManager))
            .exceptionHandling().and().csrf().disable();


        return http.build();
    }

    @Bean
    public Saml2MetadataFilter saml2MetadataFilter(){
        DefaultRelyingPartyRegistrationResolver relyingPartyRegistrationResolver
            = new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository);
        Saml2MetadataFilter filter =
            new Saml2MetadataFilter((RelyingPartyRegistrationResolver) relyingPartyRegistrationResolver,
                new OpenSamlMetadataResolver());
        return filter;
    }
}

Spring properties:

    security:
        saml2:
            relyingparty:
                registration:
                    adfs:
                        signing:
                            credentials:
                                - private-key-location: classpath:local_uat.key
                                  certificate-location: classpath:local_uat.crt
                        singlelogout:
                            binding: POST
                            response-url: "{baseUrl}/logout/saml2/slo"
                        assertingparty:
                            metadata-uri: "classpath:metadata/metadata-idp.xml"

metadata-idp.xml is loaded from adfs url: federationmetadata/2007-06/federationmetadata.xml

local_uat crt and key are generated from openssl (duration is only 30 days) for test.

So I send a SAMLRequest:

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://uat.mysite.gr/login/saml2/sso/adfs" Destination="https://adfs.uat.gr/adfs/ls/" ID="ARQ64a82b5-c9ca-469f-8454-f104b6a64203" IssueInstant="2023-05-02T08:36:39.462Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://uat.mysite.gr/saml2/service-provider-metadata/adfs</saml2:Issuer>
</saml2p:AuthnRequest>

And get back the response:

<samlp:Response ID="_1b7a62c5-f685-44d9-95e6-0ae56668a5ad" Version="2.0" IssueInstant="2023-05-02T08:36:42.664Z" Destination="https://uat.mysite.gr/login/saml2/sso/adfs" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="ARQ64a82b5-c9ca-469f-8454-f104b6a64203" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://adfs.uat.gr/adfs/services/trust</Issuer>
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
    </samlp:Status>
    <Assertion ID="_8373485d-0032-4a85-86a9-321ebc8aa930" IssueInstant="2023-05-02T08:36:42.664Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
        <Issuer>http://adfs.uat.gr/adfs/services/trust</Issuer>
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:SignedInfo>
                <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
                <ds:Reference URI="#_8373485d-0032-4a85-86a9-321ebc8aa930">
                    <ds:Transforms>
                        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                    </ds:Transforms>
                    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                    <ds:DigestValue>d29FavJeo786EfUj9HfZieHj6cx2kuB0JTM9gfKzvqc=</ds:DigestValue>
                </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>jPyA/+Sy7ibHmk4wexBZ07VPjbI/4AVu/+fmlDVDF8AF6eRz2+cOi2uNWKAqeRmVQX6hR8fEcMnJ4Zt6rCYnRVGESjla8zS2lvXnqEQ4+ewnx6j0ozgiRL1IGUsLzwM9e5xhe63ujencz/qrm6ikV/RNddLbDMNtSAP7jkaGXe7QKxjf51Inmv+VbsHu2VB3wfF0BGuK2BWDKxFyMz5/6cu2W6fqxsURa3nen7CA9j7WA7pnS+cqp0/dBO8rsbf23yygXRi3w0SQmUnfj9TKEXSCbI4Sg/V/BK120RhoRxTXB/lRsU87jKM2aIm9d/HTdH5ZUu3kBdE0mhwt+RhBog==</ds:SignatureValue>
            <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>MIIC2DCCAcCgAwIBAgIQZYNcVyIKPopPizXZ54YprDANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDEx1BREZTIFNpZ25pbmcgLSBhZGZzLnVhdG90ZS5ncjAeFw0yMzA0MDUyMTUwMTRaFw0yNDA0MDQyMTUwMTRaMCgxJjAkBgNVBAMTHUFERlMgU2lnbmluZyAtIGFkZnMudWF0b3RlLmdyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwK2x33WajCQ72Yr7EGsBUNPeNsFhRHCDMVr5ShuAEfgN0VYepfxyYSUuNEPf3LI+lyRJ8jIvrizlN2gksXPh5TkJRp4q+XzKyOyQrBFDAleiW0T+FJifw2nlI3RoWGGl/4OHD8B5JLueoW7HxI88xLeT55i5O1DxCvRALOr5Raci/gnVC6FEDiMwYmxWNJ7PB78Mb5jTXnNQfBM5xWTmhQze5TrFpehOfOEA0tLwclSrPi7Qevko1Mr4eHmtUmGt+fkEbo8hdsQnd/ELHr8oSlH71gFhEogcfNrNMvMzxu1BCqXiEiZYPmWgcQW79OtZJwus7YJewbIqdzLnEr8GhQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAQam01Iha0thgVa4iFwZLVA7H2ZR2eO1jVLyu4k125YRXMgKZSNVic1yHhT8Lq5ghW9CX4Ofag6o00cQXLc4nv9A1NpRo2glm0wE+6HJKmKfx/GMhLm+jGGZUDWHcdiIx9zOfIGUSx8X96KP9B2w8/bkQrc5OArK4rLO/polSgv5UB5Tpam/wzy/5yTc1L8DiRm3GdslEkYrfRoOotkaM4YWYVsJdQgtQsx66M4NhsWmQmC6ZTPl06ikCKmGPgoE7P+hUH3i5aUSo8/NDMPs6JL2LtedZdklkhvDnbggLvfgRcV3fQOOlrLtMQmNVXUkZcAvAVf2nDQivjyBEe6N/2</ds:X509Certificate>
                </ds:X509Data>
            </KeyInfo>
        </ds:Signature>
        <Subject>
            <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <SubjectConfirmationData InResponseTo="ARQ64a82b5-c9ca-469f-8454-f104b6a64203" NotOnOrAfter="2023-05-02T08:41:42.664Z" Recipient="https://uat.mysite.gr/login/saml2/sso/adfs" />
            </SubjectConfirmation>
        </Subject>
        <Conditions NotBefore="2023-05-02T08:36:42.664Z" NotOnOrAfter="2023-05-02T09:36:42.664Z">
            <AudienceRestriction>
                <Audience>https://uat.mysite.gr/saml2/service-provider-metadata/adfs</Audience>
            </AudienceRestriction>
        </Conditions>
        <AttributeStatement>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/implicitupn">
                <AttributeValue>[email protected]</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2017/04/identity/claims/riskscore" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue>notevaluated</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2017/04/identity/claims/accountthrottled" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue b:type="tn:boolean" xmlns:tn="http://www.w3.org/2001/XMLSchema" xmlns:b="http://www.w3.org/2001/XMLSchema-instance">false</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/claims/authnmethodsproviders">
                <AttributeValue>FormsAuthentication</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2014/01/identity/claims/anchorclaimtype">
                <AttributeValue>http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn">
                <AttributeValue>[email protected]</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid">
                <AttributeValue>S-1-5-21-573170609-2490837561-1058330354-513</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid">
                <AttributeValue>S-1-5-21-573170609-2490837561-1058330354-3707</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
                <AttributeValue>UAT\userkerbtest</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname">
                <AttributeValue>UAT\userkerbtest</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/claims/authnmethodsreferences">
                <AttributeValue>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid">
                <AttributeValue>S-1-5-21-573170609-2490837561-1058330354-513</AttributeValue>
                <AttributeValue>S-1-1-0</AttributeValue>
                <AttributeValue>S-1-5-32-545</AttributeValue>
                <AttributeValue>S-1-5-2</AttributeValue>
                <AttributeValue>S-1-5-11</AttributeValue>
                <AttributeValue>S-1-5-15</AttributeValue>
                <AttributeValue>S-1-5-21-573170609-2490837561-1058330354-2052</AttributeValue>
                <AttributeValue>S-1-5-21-573170609-2490837561-1058330354-1614</AttributeValue>
                <AttributeValue>S-1-5-21-0-0-0-497</AttributeValue>
                <AttributeValue>S-1-18-2</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue>Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.58</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue>/adfs/ls/</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue b:type="tn:boolean" xmlns:tn="http://www.w3.org/2001/XMLSchema" xmlns:b="http://www.w3.org/2001/XMLSchema-instance">true</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/2012/01/requestcontext/claims/client-request-id" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue>3778d7f8-cb2f-4308-8103-0080000000d1</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-ip" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue>10.136.113.23</AttributeValue>
            </Attribute>
            <Attribute Name="http://schemas.microsoft.com/2014/09/requestcontext/claims/userip" a:OriginalIssuer="CLIENT CONTEXT" xmlns:a="http://schemas.xmlsoap.org/ws/2009/09/identity/claims">
                <AttributeValue>10.136.113.23</AttributeValue>
            </Attribute>
        </AttributeStatement>
        <AuthnStatement AuthnInstant="2023-05-02T08:36:42.430Z">
            <AuthnContext>
                <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
            </AuthnContext>
        </AuthnStatement>
    </Assertion>
</samlp:Response>

However as described in spring i See:

Assertion [_8373485d-0032-4a85-86a9-321ebc8aa930] is missing a subject

And dependencies:

    <properties>
        <xmlsectool.version>3.0.0</xmlsectool.version>
        <opensaml.version>4.2.0</opensaml.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.7.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-web</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-client</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-saml2-service-provider</artifactId>
            <version>5.8.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
            <version>5.8.3</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-core</artifactId>
            <version>${opensaml.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-saml-api</artifactId>
            <version>${opensaml.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-saml-impl</artifactId>
            <version>${opensaml.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-soap-api</artifactId>
            <version>${opensaml.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-xmlsec-api</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-security-api</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-security-impl</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-profile-api</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-profile-impl</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-messaging-api</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-messaging-impl</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-storage-impl</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.opensaml</groupId>
            <artifactId>opensaml-xmlsec-impl</artifactId>
            <version>${opensaml.version}</version>
        </dependency>
        <!--dependency>
            <groupId>net.shibboleth.tool</groupId>
            <artifactId>xmlsectool</artifactId>
            <version>${xmlsectool.version}</version>
        </dependency-->
        <dependency>
            <groupId>org.springframework.ldap</groupId>
            <artifactId>spring-ldap-core</artifactId>
            <version>2.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.7.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

Solution

  • So after searching into spring security classes I found that spring security doesn't cohere to the saml spec which has nameid element of subject as optional. So when our adfs admin changed the returned claims and added a nameid in the subject element everything worked.