Spring Security and SAML
SAML (Security Assertion Markup Language) is an open standard for exchanging authentication and authorization data between parties. Spring Security provides robust support for integrating SAML. This guide covers key concepts and steps for setting up SAML authentication in your Spring Boot application, including adding dependencies, configuring SAML settings, and securing endpoints.
Key Concepts of Spring Security and SAML
- SAML (Security Assertion Markup Language): An XML-based framework for exchanging authentication and authorization data.
- SAML Authentication: A method to authenticate users using SAML assertions.
- Identity Provider (IdP): A service that creates, maintains, and manages identity information and provides authentication services.
- Service Provider (SP): A service that relies on an identity provider to authenticate users.
- Security Configuration: Configuring Spring Security to use SAML for authentication.
Adding Dependencies
Include the Spring Security SAML dependency in your pom.xml
file:
<dependency>
<groupId>org.springframework.security.extensions</groupId>
<artifactId>spring-security-saml2-core</artifactId>
<version>1.0.10.RELEASE</version>
</dependency>
Configuring SAML Settings
Configure SAML settings in the application.yml
file:
Example: application.yml
spring:
saml:
idp:
metadata-location: https://idp.example.com/metadata
sp:
entity-id: urn:example:sp
assertion-consumer-service-url: https://localhost:8080/saml/SSO
Configuring SAML Authentication
Configure SAML authentication by extending WebSecurityConfigurerAdapter
and creating necessary SAML beans:
Example: SecurityConfiguration.java
// SecurityConfiguration.java
package com.example.myapp.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.saml.SAMLEntryPoint;
import org.springframework.security.saml.SAMLLogoutFilter;
import org.springframework.security.saml.SAMLLogoutProcessingFilter;
import org.springframework.security.saml.metadata.MetadataDisplayFilter;
import org.springframework.security.saml.metadata.MetadataGeneratorFilter;
import org.springframework.security.saml.metadata.MetadataGenerator;
import org.springframework.security.saml.websso.WebSSOProfileConsumer;
import org.springframework.security.saml.websso.WebSSOProfileConsumerImpl;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean
public SAMLEntryPoint samlEntryPoint() {
SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint();
samlEntryPoint.setDefaultProfileOptions(webSSOProfileOptions());
return samlEntryPoint;
}
@Bean
public WebSSOProfileConsumer webSSOProfileConsumer() {
return new WebSSOProfileConsumerImpl();
}
@Bean
public MetadataGenerator metadataGenerator() {
return new MetadataGenerator();
}
@Bean
public MetadataGeneratorFilter metadataGeneratorFilter() {
return new MetadataGeneratorFilter(metadataGenerator());
}
@Bean
public MetadataDisplayFilter metadataDisplayFilter() {
return new MetadataDisplayFilter();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/saml/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(samlEntryPoint())
.and()
.addFilterBefore(metadataGeneratorFilter(), SAMLEntryPoint.class)
.addFilterAfter(metadataDisplayFilter(), MetadataGeneratorFilter.class)
.addFilterAfter(samlLogoutProcessingFilter(), SAMLLogoutProcessingFilter.class)
.addFilterBefore(samlLogoutFilter(), SAMLLogoutFilter.class);
}
@Bean
public SAMLLogoutFilter samlLogoutFilter() {
return new SAMLLogoutFilter();
}
@Bean
public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() {
return new SAMLLogoutProcessingFilter();
}
@Bean
public WebSSOProfileOptions webSSOProfileOptions() {
WebSSOProfileOptions options = new WebSSOProfileOptions();
options.setBinding(WebSSOProfileOptions.SAML2_POST_BINDING_URI);
options.setForceAuthN(false);
return options;
}
}
Creating Login and Logout Pages
Create custom login and logout pages to handle user authentication:
Example: login.html
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<link rel="stylesheet" type="text/css" href="/css/styles.css" />
</head>
<body>
<div class="swf-lsn-container">
<h2>Login</h2>
<form method="post" action="/saml/login">
<div>
<label>Username:</label>
<input type="text" name="username" />
</div>
<div>
<label>Password:</label>
<input type="password" name="password" />
</div>
<div>
<input type="submit" value="Login" />
</div>
</form>
<div class="swf-lsn-error-message">
<#if error?string?trim != "">
Invalid username or password.
</#if>
<#if logout?string?trim != "">
You have been logged out.
</#if>
</div>
</div>
</body>
</html>
Securing Endpoints
Protect specific endpoints by specifying access rules:
Example: SecurityConfiguration.java
// SecurityConfiguration.java
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/saml/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(samlEntryPoint())
.and()
.addFilterBefore(metadataGeneratorFilter(), SAMLEntryPoint.class)
.addFilterAfter(metadataDisplayFilter(), MetadataGeneratorFilter.class)
.addFilterAfter(samlLogoutProcessingFilter(), SAMLLogoutProcessingFilter.class)
.addFilterBefore(samlLogoutFilter(), SAMLLogoutFilter.class);
}
Key Points
- SAML (Security Assertion Markup Language): An XML-based framework for exchanging authentication and authorization data.
- SAML Authentication: A method to authenticate users using SAML assertions.
- Identity Provider (IdP): A service that creates, maintains, and manages identity information and provides authentication services.
- Service Provider (SP): A service that relies on an identity provider to authenticate users.
- Security Configuration: Configuring Spring Security to use SAML for authentication.
- Include the Spring Security SAML dependency in your
pom.xml
file. - Configure SAML settings in the
application.yml
file. - Configure SAML authentication by extending
WebSecurityConfigurerAdapter
and creating necessary SAML beans. - Create custom login and logout pages to handle user authentication.
- Protect specific endpoints by specifying access rules.
Conclusion
Integrating SAML with Spring Security allows you to leverage the power of SAML for secure authentication in your Spring Boot applications. By understanding and configuring SAML settings, security configuration, and authentication flows, you can ensure secure access to your application's resources. Happy coding!