Hello Okta Community,
I am encountering an issue with my SAML integration and need some assistance to diagnose the problem. Below is the SAML response I am receiving and my current application configuration for Okta:
Problem:
“”
Login with SAML 2.0
Invalid assertion [id1876397057065964234432259] for SAML
response (id18763970568562192127533068]: Condition
{urn:oasis:names:tc:SAML:2.0
)AudienceRestriction’ of
type ‘null’ in assertion ‘id1876397057065964234432259’ was not
valid: None of the audiences within Assertion
‘id1876397057065964234432259’ matched the list of valid
audiances
“”
SAML Response:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response Destination="http://backend/login/saml2/sso/backendsh" ID="id17789585412712011876155695" IssueInstant="2024-06-13T10:51:36.392Z" Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.okta.com/exkzxipdxdvlXAB1t7</saml2: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="#id17789585412712011876155695">
<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#">
<ec:InclusiveNamespaces PrefixList="xs" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>8/NCvSRmWXYRaUIj5KmVxWmpzkaA4k53J56MT++sl50=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>b9Rib79UkGYNDsRffAGxzmQdpp4Sr/3730mScpDxBE24DULMXNG8CjD7IudPDSMJnds7CgxGVHyZ6dMwIOKQrUoDZHKtsb6x4cxQLGgXbYMVMF5XcR/iaS0jhqjOfMev51p5OAznZyCPO7kf9dRhkHpgMuDJXVJYyTfxOx/aU5FvfEhfYBG+aBV33dVoGMDm2DMcTnq6JZfUf4XoIKdM2iWGgz1dH4VabSSL1csDneT2mC4eiPekbqMASr2XLNl4GAmTFSEIoGEI7Pi0oiqQjS6D3BpS85sETf9Eeyg7tIRm3cta11JugTynm2N88Qi8X6S0zXgSwliD8inBAhHQdA==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</saml2p:Status>
<saml2:Assertion ID="id17789585414602721408698751" IssueInstant="2024-06-13T10:51:36.392Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.okta.com/exkzxipdxdvlXAB1t7</saml2: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="#id17789585414602721408698751">
<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#">
<ec:InclusiveNamespaces PrefixList="xs" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>hIS48V8fBmgnjLihHTd8YQVPoXQZYRAUeE0q8LvqT64=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>rTmxAVvgbIz1T98+4swBKvLUae6dxD2QXg/oW5NIFAmNE/hG3947vBCbHwph2iwuxSObxfC1c9Uz1iqPN3HAPf1eR4cDiNPDLvea3OCa0ntZJOuqQNYyQLEhHfgtsoDavkXIjQilxzjv7Tcc5a6opUbjQ7Y+NvTtvee4dduDe8R7Hh5PuXU7bt7tJ8flKEiWsNe8zbDo3HrfooPrvKqEI8ZIVl0gIo4z5EFZZWCcW6rS0vtBT6/f3QSNgfk8tn8VX1c/lTsX1Dwcoz5deAzfrR3biDsqYRFt1p9xaRDN3aLRxwemqscNIShPmttxomRWN8/yLUbAPgG6ZQi6XFw3Lg==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
...
</saml2:Assertion>
</saml2p:Response>
Spring boot configuration
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath />
</parent>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-saml2-service-provider</artifactId>
</dependency>
@Configuration
@EnableWebSecurity
@ConditionalOnProperty(name = "use.okta", havingValue = "true", matchIfMissing = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${registration.id}")
private String registrationId;
@Value("${entity.id}")
private String entityId;
@Value("${single.signOn.service.location}")
private String singleSignOnServiceLocation;
@Value("${ac.service.location}")
private String acServiceLocation;
@Autowired
private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
// http
// .authorizeRequests(authorize ->
// authorize.anyRequest().authenticated()
// ).saml2Login()
// // Your SAML 2.0 configuration
// .and()
// // Disable CSRF
// .csrf().disable()
// // Disable CORS
// .cors().disable();
http
.authorizeRequests()
.antMatchers("/okta/currentSession").permitAll() // Permit access to a specific API endpoint without authentication
// Add more antMatchers as needed for other endpoints
// Define anyRequest authentication rule AFTER specific antMatchers
.anyRequest().authenticated()
.and()
.saml2Login()
// Your SAML 2.0 configuration
.and()
.csrf().disable()
.cors();
// add auto-generation of ServiceProvider Metadata
Converter<HttpServletRequest, RelyingPartyRegistration> relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver(relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
http.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class);
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOriginPatterns(Collections.singletonList("*")); // Set allowed origin patterns
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
@Bean
protected RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exception {
Resource resource = new ClassPathResource("saml-certificate/okta.crt");
if (!resource.exists()) {
throw new FileNotFoundException("Certificate file not found");
}
try (InputStream inputStream = resource.getInputStream()) {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(inputStream);
Saml2X509Credential credential = Saml2X509Credential.verification(certificate);
RelyingPartyRegistration registration = RelyingPartyRegistration
.withRegistrationId(registrationId)
.assertingPartyDetails(party -> party
.entityId(entityId)
.singleSignOnServiceLocation(singleSignOnServiceLocation)
.wantAuthnRequestsSigned(false)
.verificationX509Credentials(c -> c.add(credential))
).assertionConsumerServiceLocation(acServiceLocation) // Ensure ACS URL is set correctly
.build();
return new InMemoryRelyingPartyRegistrationRepository(registration);
}
}
//Not in use
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Your authentication provider configurations here
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
application properties
registration.id: 'backendsh'
entity.id: http://www.okta.com/exkzxipdxdvlXAB1t7
single.signOn.service.location: https://xxx.okta.com/app/xxx_xxx_1/exkzxipdxdvlXAB1t7/sso/saml
use.okta: 'true'
ac.service.location: http://backend/login/saml2/sso/backendsh
server.ssl.enabled: 'false'
Despite configuring everything according to the Okta documentation, users are unable to sign in successfully. I suspect there might be an issue with the SAML response or the application configuration, but I’m unable to pinpoint it.
Could anyone provide insights into potential misconfigurations or common pitfalls in similar scenarios? Any assistance would be greatly appreciated!
Thank you in advance!