TL;DR: In this article, you will learn how to create and secure a jQuery SPA and a Spring Boot API using OAuth 2.0. You will start by scaffolding a new Spring Boot project. Then you will add some endpoints to it. After that, you will use Spring Security to secure the whole thing. Lastly, you will create a SPA (with jQuery) to consume the API. If needed, you can find the reference code developed throughout the article in this GitHub repository.

What is OAuth 2.0?

Nothing better then the official specification itself to teach you what OAuth 2.0 is:

OAuth 2.0 is an authorization framework that enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner (usually a user) or by allowing a third-party application to obtain access on its own behalf. - The OAuth 2.0 Authorization Framework

OAuth 2.0 and Single-Page Apps: using the Implicit Grant

Since you are going to develop a demo application that is composed of a Single-Page App (SPA) that consumes resources from a Spring Boot API that is secured with OAuth 2.0, you will have to implement what is known as the OAuth 2.0 Implicit Grant. The Implicit Grant is an OAuth 2.0 flow specifically tailored for public SPAs clients that want to consume APIs. If you were developing a different kind of client (for example, a mobile app), you would have to choose another flow.

Securing Spring Boot APIs with OAuth 2.0

In this section, you will start from scratch, create a new Spring Boot API, secure it with OAuth 2.0, and then create a SPA to consume this API. However, before you can dive deep in the code, you will need an identity provider that implements the OAuth 2.0 protocol. For this demo application, you will use Auth0 and, for that, you'll need to sign up for a free Auth0 account here.

After signing up for your Auth0 account, you will need to create an API on Auth0 to represent your backend API and to be able to configure it to authenticate requests. To do this, head to the APIs section on your Auth0 dashboard and click on the Create API button. After that, the dashboard will show you a form where you will have to enter:

a name for your API (this can be something like "Spring Boot Implicit Flow");

an identifier (in this case, it can be http://localhost:8080/api or anything that resembles a valid URL);

and the signing algorithm (for this field, make sure you choose RS256).

Then, you can create your Auth0 API by clicking on the Create button.

After clicking on this button, the dashboard will redirect you to a section where you will find instructions on how to configure your backend. As this article will address everything related to the configuration, you can ignore this section and move to the Scopes section. There, you will register an OAuth scope:

Name: read:messages

Description: "Read messages"

After inserting the above values on the form, hit the Add button to save this new scope into your Auth0 API. With this in place, you are done with the configuration and can start working on your backend API.

Scaffolding Your Spring Boot API

In this section, you will create a new Spring Boot application that will serve as your API. This API will expose public and private endpoints. For starters, go to the Spring Initializr page and fill out the form like this:

Generate a: Gradle Project

with: Java

and Spring Boot: 2.0.x

Group: com.example

Artifact: spring-boot-oauth2

Then, on the Dependencies section, you will have to use the search box to include two libraries: Web and Security.

After filling out the form, click on the Generate Project button to download your new application. When your browser finished downloading it, extract the contents of the downloaded file and import the project into your preferred IDE.

As you can see through your IDE, for now, your project contains only one class called SpringBootOauthApplication. If you open the build.gradle file, you will also see that your project defines four dependencies: spring-boot-starter-security, spring-boot-starter-web, spring-boot-starter-test, and spring-security-test. If you are using Java 10, you will have to update this file to include a library that handles Java to XML marshalling:

After inserting this code, your IDE will probably start yelling at you because it does not know where to find the org.json.JSONObject class. To solve this issue, add the following dependency to your build.gradle file:

With that in place, the next thing you will need to do is to define the environment variables that the AppController class consumes. That is, if you take a close look at this class, you will see that it contains three String fields annotated with @Value:

Just make sure you replace <DOMAIN> and <AUTH0-API-IDENTIFIER> with your own Auth0 values. Don't worry about the <CLIENT-ID> placeholder now, you will replace it later.

Securing the Spring Boot API with OAuth 2.0

Now that you have defined your endpoints, it is time to secure your API using OAuth 2.0. To do so, you are going to import another library provided by Spring that will facilitate the configuration of everything. So, open the gradle.build file and add the following dependency to it:

As you can see, you annotated this class with @EnableResourceServer. This annotation is a convenient feature for resource servers secured with OAuth 2.0 as it automatically enables a Spring Security filter that authenticates requests via an incoming OAuth 2.0 token. Besides this annotation, this class contains the following methods:

configure(ResourceServerSecurityConfigurer resources), used to set the identifier of your API (e.g., http://localhost:8080/api);

configure(HttpSecurity http), used to specify which API endpoints are secured (in this case, mvcMatchers("/api/**").authenticated()), which are secured and require a particular scope (i.e., antMatchers("/api/private-scoped").access("#oauth2.hasScope('read:messages')")), and which endpoints are public (i.e., mvcMatchers("/api/public").permitAll()).

The only problem now is that the SecurityConfig class does not know how to verify your access token. That is, whenever your users send requests to your secured endpoints, they will include access tokens that are signed with a private key. In order for this class to know if it can trust or not these access tokens, Spring will need the public key that pairs with this private key used to sign the token. To get this public key, your backend API will need to issue a request to an endpoint known as the JWKS endpoint. You don't really have to understand the details about how this works but, if you are curious, you can read all about it here and on the official specification.

Suffices to say that, for your Spring Boot API to get a copy of the public key used to validate access tokens, you will have to open the application.properties file and add the following property into it:

Note: You will have to replace <DOMAIN> with your own Auth0 domain. Just like you did before while configuring the auth0.domain environment variable.

From the backend API point of view, this is everything you need to define endpoints and to secure them with OAuth 2.0. The next section will focus on creating and defining a client app (a SPA) to consume this API. Basically, this SPA will be responsible for three things:

enabling users to authenticate;

getting access tokens back from the authentication server (Auth0);

enabling users to use this access tokens to issue requests to your new Spring Boot API.

Creating and Securing a SPA with the OAuth 2.0 Implicit Grant

In this section, you are going to create a jQuery SPA that will interact with your Spring Boot API. Before starting, you will need to create an Auth0 Application to represent your SPA. To do so, head to the Applications page in your Auth0 dashboard and click on Create Application. After clicking on it, Auth0 will show a dialog where you will have to input a name for your app (you can call it "Spring Boot Client SPA" or anything like that) and define the type of the application. As you are going to build an app that resembles a SPA, choose the Single Page Web Applications type.

Now, clicking on the Create button will make Auth0 redirect you to the Quick Start section of your new app. From there, click on the Settings tab and add http://localhost:8080 to the Allowed Callback URLs field. As a security measure, Auth0 will only redirect users (after the authentication process) back to the URLs listed on this field (i.e., whenever you move into production, make sure you have a configuration that only lists your real internet domain). Now, click on Save Changes.

After saving it, copy the value showed on the Domain field and insert it after auth0.domain= in the application.properties field (if you haven't done so yet). Then, copy the value showed on the Client ID field and use it to replace <CLIENT-ID> in this same file. In the end, your file will look like this:

With that covered, you are ready to create your SPA. For starters, create an assets directory under /src/main/resources/static. This is where you are going to put all files related to your client application.

Now, create a new file called style.css inside the assets directory and fill it with the following CSS rules:

This is just a Cascading Style Sheets (CSS) file to make your client app look nice. Now, you need a page for your SPA. So, create an index.html page in your static directory and fill it with the following content:

It is worth noting that this file includes Bootstrap's CSS library and your custom stylesheet (style.css) in the head element. Also, before the closing body tag, this file includes Bootstrap's JavaScript library, Auth0's JavaScript library, [jQuery])(https://jquery.com/), and a local JavaScript file called app.js. Don't worry about the missing app.js, you will create it in no time.

Now, if you take a closer look at the HTML definition, you will see that your page contains eight buttons:

Home (btn-home-view): This button will show the default view.

Profile (btn-profile-view): This button will show a view with the profile of the logged-in user.

Ping (btn-ping-view): This button will show a view where users will be able to issue different types of requests.

Log In (btn-login): This button will start the authentication process.

Log Out (btn-logout): This button will log out the current user.

Call Public (btn-ping-public): This button will call the public endpoint (/api/public) and show the returned message.

Call Private (btn-ping-private): This button will call one of the private endpoints (/api/private in this case) and show the returned message.

Call Private Scoped (btn-ping-private-scoped): This button will call the other private endpoint (/api/private-scoped) and show the returned message.

The rest of the elements defined in this HTML file is there so you can show users' profiles, messages returned by the server, etc.

Now, the last thing you will need to do is to create the app.js file in the assets directory. After creating it, add the following code to this file:

As you can see, this file is quite big (almost 150 lines of JavaScript code). However, it's easy to understand what is going on there. First, your script is waiting until the document is ready ($('document').ready(...)) before doing anything. When your document is ready, your script prepares the client app by:

issuing an AJAX request to http://localhost:8080/api/config to read some environment variables;

configuring an Auth0 client (var webAuth = new auth0.WebAuth(...)) with these variables;

and by defining and attaching event listeners to the buttons defined in your HTML file.

Another important thing that this script does is to define a function that is responsible for fetching user details after they authenticate through Auth0. If you take a look, you will see a function called handleAuthentication inside this script. This function calls webAuth.parseHash to fetch two things returned by Auth0:

accessToken: Your script will use this token while issuing requests to the secured endpoints in your Spring Boot API.

idTokenPayload: Your client app will use this info to display information about the logged-in user.

That's it! You are ready to run your Spring Boot API and to consume it through this simple SPA. So, open a terminal and execute the following commands:

Note: If you imported your project correctly inside your IDE, you will probably be able to run through the IDE's interface.

After running your app, if you head to http://localhost:8080, you will see a screen where you will be able to login.

After logging in, you will be redirected back to the SPA where you will see a similar screen but with some other buttons. If you click on the Ping button, you will see a section where you will have three options. The first one will be a button to issue requests to the public endpoint. The second one will be a button to issue requests to the endpoint that is secured, but that doesn't require any scopes. The last option will be a button that issues requests to the endpoint that is both secured and that requires a scope (in this case, read:messages). Clicking on any of these buttons will issue requests to your Spring Boot API and will output the result on the screen.

Conclusion

In this article, you learned how to create and secure a Spring Boot API with OAuth 2.0 using the official OAuth 2.0 library provided by the framework. You also took a quick look at how to create and authenticate a SPA so that it can consume your Spring Boot API. If you are interested in learning more about OAuth 2.0 and its Spring Boot support, visit the following links:

Again, you can find the accompanying repository and code developed throughout this article in this GitHub repository. If you have comments or questions, don't hesitate to reach out to us through the comments area down there. I hope you enjoyed.