Implementing SAML-based Single Sign-On (SSO) with Spring Security allows applications to delegate authentication to external Identity Providers (IdPs) like Okta, ADFS, or Azure AD. This guide explains how to configure Spring Security’s SAML Extension, set up local and remote metadata, and map user attributes for seamless integration.
1. Configuring Spring Security SAML Extension
Prerequisites
- Java 8+
- Spring Boot 2.x/3.x
spring-security-saml2-service-provider
dependency
Step 1: Add Dependencies
Include the following in your pom.xml
(Maven) or build.gradle
(Gradle):
Maven:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-saml2-service-provider</artifactId>
<version>5.7.0</version>
</dependency>
Gradle:
implementation 'org.springframework.security:spring-security-saml2-service-provider:5.7.0'
Step 2: Configure SAML in application.yml
Define the SAML properties in your configuration file:
spring:
security:
saml2:
relyingparty:
registration:
idp-name:
identityprovider:
entity-id: urn:example:idp
singlesignon.url: https://idp.example.com/saml2/sso
verification.credentials:
- certificate-location: classpath:idp-certificate.pem
Step 3: Enable SAML in Security Configuration
Extend WebSecurityConfigurerAdapter
(Spring Boot 2.x) or use SecurityFilterChain
(Spring Boot 3.x):
Spring Boot 3.x Example:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain samlFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.saml2Login(saml2 -> saml2
.relyingParty(rp -> rp
.registration(registration -> registration
.entityId("urn:example:sp")
.assertingParty(party -> party
.entityId("urn:example:idp")
.singleSignOnServiceLocation("https://idp.example.com/saml2/sso")
.verificationCredentials(c -> c
.certificateLocation("classpath:idp-certificate.pem")
)
)
)
)
);
return http.build();
}
}
2. Local and Remote Metadata Setup
Local Metadata (SP Metadata)
Spring Security can generate SP metadata dynamically or use a static file.
Generate Dynamically:
Access /saml2/service-provider-metadata/{registrationId}
(e.g., /saml2/service-provider-metadata/idp-name
).
Static Metadata File:
- Create an XML file (e.g.,
sp-metadata.xml
) with your SP details. - Configure it in
application.yml
:
spring:
security:
saml2:
relyingparty:
registration:
idp-name:
serviceprovider:
entity-id: urn:example:sp
metadata-location: classpath:sp-metadata.xml
Remote Metadata (IdP Metadata)
Provide the IdP’s metadata URL or file:
Via URL:
spring:
security:
saml2:
relyingparty:
registration:
idp-name:
identityprovider:
metadata-uri: https://idp.example.com/metadata.xml
Via File:
metadata-location: classpath:idp-metadata.xml
3. User Attribute Mapping (AttributeMapping)
SAML assertions include user attributes (e.g., email
, name
). Map these to Spring Security’s Principal
:
Default Attribute Mapping
Spring Security automatically maps:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
→Principal.getName()
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
→Principal.getAttribute("given_name")
Custom Mapping
Override defaults in SecurityConfig
:
.saml2Login(saml2 -> saml2
.relyingParty(...)
.userDetailsService(userDetailsService())
.attributeMapping(attrs -> attrs
.name("email") // Maps NameID or specified attribute to Principal
.samlAttribute("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")
)
)
Example: Extract Roles from SAML
.saml2Login(saml2 -> saml2
.attributeMapping(attrs -> attrs
.roles("http://schemas.microsoft.com/ws/2008/06/identity/claims/role")
)
)
4. Full Flow Example with Metadata
-
User Visits
/login
:- Redirects to IdP’s SSO URL (
https://idp.example.com/saml2/sso
).
- Redirects to IdP’s SSO URL (
-
IdP Authenticates User:
- Returns a SAML response to
/saml2/acs
(Assertion Consumer Service).
- Returns a SAML response to
-
Spring Security Validates Assertion:
- Verifies the signature using the IdP’s certificate.
- Maps attributes to
Principal
.
-
User Granted Access:
- Authenticated session established.
Conclusion
Spring Security’s SAML extension simplifies integration with SAML-based IdPs. Key steps include:
- Configuring dependencies and properties.
- Setting up SP/IdP metadata (local or remote).
- Customizing attribute mapping for user details.
For advanced scenarios, refer to the Spring Security SAML Documentation.