Spring Security, Powered by MSAL Part 2 (Resource Server)

Adeogo Oladipo
3 min readMay 2, 2022

In the Part 1 of this series, we discussed the most common mode of integrating MSAL; the Client Auth Mode.
In this article, we will look at another common use case; the Resource Server Mode.

Use Case

Let’s say you have an application with and API endpoint you would like to expose to another application in your organization. We can achieve this with Spring Security and MSAL in resource_server mode.

For this use case, we will use two App Registrations, One for the Resource Server and another for the API Client/ API Consumer.

App Registrations Setup

Resource Server App Registration Setup

After creating the App Registration, we will need to set the Application ID URI, as shown below

How to set Application ID URI

After setting the Application ID URI, we can create some App Roles for Authorization, to limit the route Api Consumers are allowed to access based on what roles we assign to them.

How to create App Roles

Api Consumer App Registration Setup

After we’ve created the App Roles, We can switch over to the Api Consumer App Registration. There all we need to do is to Add the Api permission. The App Roles created in the previous step will appear as Api Permissions to the Api Consumer App Registration.

Api Permissions — -> Add a permission — ->My APIs — ->Application Permissions

This should be all that is required to be done in Azure Portal.

Resource Server Code Implementation

Dependencies

<properties>
<java.version>11</java.version>
<azure.version>3.11.0</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-active-directory</artifactId>
<version>${azure.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

application.yml

azure:
activedirectory:
application-type: resource_server
app-id-uri: ${APP_ID_URI}
tenant-id: ${AZURE_TENANT_ID}
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
user-group:
allowed-group-names: group_name_1, group_name_2

SecurityAdapter

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2Config extends AADResourceServerWebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.antMatcher("/api/**").authorizeRequests().anyRequest().authenticated();
}
}

RestController

@RestController
public class DemoController {

@GetMapping(value = "/api/demo")
public String demo() {
return "demo";
}
}

Authenticating the API Consumer

curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token \
-d 'client_id=<client-id>' \
-d 'grant_type=client_credentials' \
-d 'scope=#API_ID_URI#.default' \
-d 'client_secret=<client-secret>'

This would return an access_token. To make a request to the Resource Server

curl --location --request GET 'http://localhost:8080/api/demo/' \
--header 'Authorization: Bearer access_token'

The source code for this article can be found on Github.

--

--

Adeogo Oladipo

Co-Founder and CTO @DokitariUG. A Strong believer in the Potential in Each Human.