Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

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!