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>userkerbtest@uat.gr</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>userkerbtest@uat.gr</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>
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.