OAuth 2.0: Authorization Code Flow in Spring Boot

Dev INTJ Code
Javarevisited
Published in
5 min readFeb 7, 2022

Learn the what, when, and how.

Introduction

In this tutorial, we’ll discuss the following:

  • What’s the authorization code flow
  • When it’s appropriate to use over other OAuth flows
  • How to implement it in Spring Boot

Above, with the sequence diagram, we can see the entire flow. Let’s talk about it in detail as we go along.

Given we’ve got a lot to cover, let’s dive right in!

What is the Authorization Code Flow?

“The Authorization Code Flow in OAuth 2.0 is a process in which a client obtains an authorization code from an authorization server and then uses the code to acquire access tokens from the token server.” — GPT-3.

With that, Let’s take a step back and compare the flow in real-world objects to visualize it better:

Imagine walking into a Hotel. We, as the client, need access to a room (resource). Then, to request a key, we talk to the front desk. The front desk acting like an authorization server would probably ask for our identification (comparable to authentication in this case).

Assuming that everything’s good, the front desk will hand us over a key (access token). Finally, now we can access the room (Let’s hope and assume that the key at hand is the right one).

When it’s appropriate to use over other OAuth flows

Before anything else, let’s see some of the flows (not exhaustive):

  • Authorization Code
  • Authorization Code w/ PKCE
  • Resource Owner
  • Client Credentials

With these in place, let’s take a closer look at our sequence diagram. Notice that authentication only happens in the Authorization Server. On the other hand, authorization takes place at most between the client (traditional/server-side app) and Authorization Server — making the access token hidden and inaccessible to users.

Because of these, Authorization Code Flow tends to be the most secured by default; however, as mentioned earlier, it’s only appropriate if our client is a traditional/server-side application.

If we have client-side apps such as Mobile Apps/SPAs/PWAs, it’s better to use Authorization Code w/ PKCE. Next, on the contrary, the Resource Owner Flow has delegated both the authentication and authorization to the client app itself instead of the Authorization Server, which makes it pretty insecure — unless it’s an internal application we manage ourselves.

Lastly, the Client Credentials flow is for communication between services where users aren’t involved — meaning it’s also not applicable in our case.

How to implement it in Spring Boot

First, preparatory to its implementation, it’s worth mentioning the release of the Spring Authorization Server project last August 19, 2021 — thus, making the Spring Security OAuth project deprecated.

With that, let’s use spring-security-oauth2-authorization-server as the dependency:

Now, let’s check the authorization server capabilities. Conveniently, with RFC-8414 — OAuth 2.0 Authorization Server Metadata, we can get this information in JSON format:
curl -X GET http://localhost:9000/.well-known/oauth-authorization-server

(Alternatively, we can also install jq to beautify the JSON response:
curl -X GET http://localhost:9000/.well-known/oauth-authorization-server | jq .)

From this response, we can see that both authorization endpoint and token endpoint are readily available.

Next, we have to figure out the core components or interfaces that need concrete implementations. Here’s the official getting started video guide:

It was a great demo. Anyway, here are the main components:

  • OAuth2AuthorizationServerConfiguration
  • ProviderSettings
  • JWKSource
  • RegisteredClientRepository
  • OAuth2AuthorizationService
  • OAuth2AuthorizationConsentService

Let’s begin by creating an AuthorizationServerConfig. On this configuration, let’s define the beans of SecurityFilterChain, ProviderSettings, and JWKSource:

For brevity, we’ve omitted some parts from the gist. Anyway, about the authServerSecurityFilterChain method, we’ve applied the default security for simplicity; however, take note that we need to implement a custom one if there’s a requirement for Dynamic Client Registration.

Next, for the remaining repository and services, let’s utilize the available concrete implementations from the spring-security-oauth2-authorization-server dependency (instead of implementing our own) by defining the following beans:

The above beans will perform the necessary validations and the persistence logic from both the token endpoint and authorization endpoint.

Moving on, we need to have the provided schema for the corresponding tables in our database. It’s in the resource folder of the dependency:

Lastly, let’s collate it all into a schema.sql file for simplicity:

Demo

First, let’s run both the Authorization Server and Resource Server. (All sources are available on the Github link below.)

Now, let’s use our sequence diagram as a reference. Suppose we need to retrieve a list of articles from the resource server. Since we aren’t past authentication yet, a redirection to the authorization server should occur. Let’s paste this URL on a browser to simulate:
http://localhost:9000/oauth2/authorize?response_type=code&scope=articles.read%20articles.write&client_id=articles-client&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/articles-client-oidc

Now that the Authorization Server serves the login page — let’s enter our credentials. (If you’re following along, it’s “username” for the username and “password” for the password):

This time, the Authorization Server serves the consent page. On the other hand, we can skip this if we set the registered client settings to make it optional. Anyway, let’s now submit the form:

Now that we got redirected to the client app url — let’s examine the parameters. Instead of building a client app, let’s simulate acquiring the access token using postman.

First, for the Authorization, let’s use the Basic Auth — and set the registered client’s username and password:

Next, for the parameters, let’s have the following:

  • grant_type: authorization_code
  • redirect_uri: <registered client’s configured redirect uri>
  • code: <the generated authorization code from the ealier URL>

Lastly, given the access token, let’s try to retrieve the articles from the resource server (again using postman):

That’s it!

Conclusion

Using the Spring Authorization Server as a dependency, we had rolled out an Authorization Server. We then implemented the necessary parts and had successfully simulated the Authorization Code Flow.

However, as much fun as it is, in my opinion, if you’ll ever need an authorization server on your projects, it’s best to use available and trusted platforms like Okta. I’m not in any way affiliated with Okta (I wish I am though 😆). I’m just a fan of their services, as well as initiatives — like the OAuth Playground.

Anyways, as always, the source code is available on GitHub.

--

--

Dev INTJ Code
Javarevisited

Senior Software Engineer specializing in Backend Development, particularly in Java, utilizing the tech within the Spring Framework ecosystem;