Get Started with Spring Boot and SAML
Tags: springboot, java, saml
Published: 2022-08-24 12:48:58

### Learn how to build a Spring Boot application that authenticates against Okta and Auth0 with Spring Security's SAML support.

### <br>

Spring is a long-time friend to enterprise companies throughout the world. When Spring Boot came along in 2014, it greatly simplified configuring a Spring application. This led to widespread adoption and continued investment in related Spring projects.

One of my favorite Spring projects is Spring Security. In most cases, it simplifies web security to just a few lines of code. HTTP Basic, JDBC, JWT, OpenID Connect/OAuth 2.0, you name it—Spring Security does it!

You might notice I didn’t mention SAML as an authentication type. That’s because I don’t recommend it. The specification for SAML 2.0 was published in March 2005, before smartphones or smart devices even existed. OpenID Connect (OIDC) is much easier for developers to use and understand. Using SAML in 2022 is like implementing a web service using WS-* instead of REST.

My recommendation: just use OIDC.

If you _must_ use SAML with Spring Boot, this tutorial should make it quick and easy.

**Prerequisites:**

* [SDKMAN](https://sdkman.io/) (for Java 17)

## What is SAML?

**S**ecurity **A**ssertion **M**arkup **L**anguage is an XML-based way of doing web authentication and authorization. It works cross-domain, so SaaS applications and other enterprise software often support it.

Nick Gamb has an excellent overview in [A Developer’s Guide to SAML](https://www.youtube.com/watch?v=l-6QSEqDJPo).


{% youtube l-6QSEqDJPo%}

If you want to learn how Spring Security implements SAML, please read its [SAML 2.0 Login docs](https://docs.spring.io/spring-security/reference/servlet/saml2/login/index.html).

## Add a SAML Application on Okta

To begin, you’ll need an Okta developer account. You can create one at [developer.okta.com/signup](https://developer.okta.com/signup) or install the [Okta CLI](https://cli.okta.com/) and run `okta register`.

Then, log in to your account and go to **Applications** > **Create App Integration**. Select **SAML 2.0** and click **Next**. Name your app something like `Spring Boot SAML` and click **Next**.

Use the following settings:

* Single sign on URL: `http://localhost:8080/login/saml2/sso/okta`
* Use this for Recipient URL and Destination URL: ✅ (the default)
* Audience URI: `http://localhost:8080/saml2/service-provider-metadata/okta`

Then click **Next**. Select the following options:

* I’m an Okta customer adding an internal app
* This is an internal app that we have created

Select **Finish**.

Okta will create your app, and you will be redirected to its **Sign On** tab. Scroll down to the **SAML Signing Certificates** and go to **SHA-2** > **Actions** > **View IdP Metadata**. You can right-click and copy this menu item’s link or open its URL. Copy the resulting link to your clipboard. It should look something like the following:

```
https://dev-13337.okta.com/app/<random-characters>/sso/saml/metadata
```

Go to your app’s **Assignment** tab and assign access to the **Everyone** group.

## Create a Spring Boot App With SAML Support

Spring Boot 3 requires Java 17. You can install it with SDKMAN:

```
sdk install java 17-open
```

The easiest way to do this tutorial is to clone the existing [Spring Boot example application](https://github.com/oktadev/okta-spring-boot-saml-example) I created.

```
git clone https://github.com/oktadev/okta-spring-boot-saml-example.git
```

If you’d rather start from scratch, you can create a brand-new Spring Boot app using [start.spring.io](https://start.spring.io/). Select the following options:

* Project: **Gradle**
* Spring Boot: **3.0.0 (SNAPSHOT)**
* Dependencies: **Spring Web**, **Spring Security**, **Thymeleaf**

![spring initializr](https://images.ctfassets.net/23aumh6u8s0i/1opOtPoqV5WHovXqL2bTs7/d1c5fcb60971639ded27c5c88c4e7383/01_start_spring_io.png)

You can also use [this URL](https://start.spring.io/#!type=gradle-project&language=java&platformVersion=3.0.0-SNAPSHOT&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=web,security,thymeleaf) or HTTPie:

```
https start.spring.io/starter.zip bootVersion==3.0.0-SNAPSHOT \
  dependencies==web,security,thymeleaf type==gradle-project \
  baseDir==spring-boot-saml | tar -xzvf -
```

If you created a brand-new app, you’ll need to complete the following steps:

1. Add `src/main/java/com/example/demo/HomeController.java` to populate the authenticated user’s information. 


```java
package com.example.demo;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {

    @RequestMapping("/")
    public String home(@AuthenticationPrincipal Saml2AuthenticatedPrincipal principal, Model model) {
        model.addAttribute("name", principal.getName());
        model.addAttribute("emailAddress", principal.getFirstAttribute("email"));
        model.addAttribute("userAttributes", principal.getAttributes());
        return "home";
    }

}
```


2. Create a `src/main/resources/templates/home.html` file to render the user’s information.

```html
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6">
<head>
    <title>Spring Boot and SAML</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>

<h1>Welcome</h1>
<p>You are successfully logged in as <span sec:authentication="name"></span></p>
<p>Your email address is <span th:text="${emailAddress}"></span>.</p>
<p>Your authorities are <span sec:authentication="authorities"></span>.</p>
<h2>All Your Attributes</h2>
<dl th:each="userAttribute : ${userAttributes}">
    <dt th:text="${userAttribute.key}"></dt>
    <dd th:text="${userAttribute.value}"></dd>
</dl>

<form th:action="@{/logout}" method="post">
    <button id="logout" type="submit">Logout</button>
</form>

</body>
</html>
```

3. Create a `src/main/resources/application.yml` file to contain the metadata URI you copied in [Add a SAML application on Okta](https://developer.okta.com/blog/2022/08/05/spring-boot-saml#add-a-saml-application-on-okta). This value should end with `/sso/saml/metadata`.


```
spring:
  security:
    saml2:
      relyingparty:
        registration:
          okta:
            assertingparty:
              metadata-uri: <your-metadata-uri>
```

4. Then, change `build.gradle` to add Spring Security SAML's dependency:

```
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
implementation 'org.springframework.security:spring-security-saml2-service-provider'
```

If you cloned from GitHub, you only need to update `application.yml` to include your metadata URI. You can remove the other properties as they may cause issues.

[Read more...](https://auth0.com/blog/get-started-with-spring-boot-and-saml/?utm_source=content_synd&utm_medium=sc&utm_campaign=global_dist)