Image of Spring Boot + Spring Security + OAuth2

ADVERTISEMENT

Table of Contents

Introduction

In this tutorial we explain how to secure a Spring Boot application using OAuth2.

If you follow the steps in order, you’ll get a fully working secured application which authenticates user requests through Google API.

Prerequisites:

  • Eclipse IDE (neon release)
  • Maven 4
  • Java 1.8
  • Spring Boot 2.0.0

1- Create maven project

Open eclipse then create a new maven project and name it as SpringBootOAuth2.

At the end of this tutorial, we’ll get the following project structure:

folder structure

2- pom.xml

Configure Spring Security in the application through adding the following dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

After adding this dependency, you will not be able to access any page in the application without being authenticated through the traditional Spring login page.

In order to avoid the traditional Spring authentication and use external service authentication, we add support for OAuth2 as the following:

<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>

For now Spring Boot still doesn’t know which OAuth2 service you’re going to integrate with, so you’ll still see the traditional login page.

Now just define your application as a web app through adding the following dependencies:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

We add “tomcat-embed-jasper” to be able to use JSP later on in the tutorial.

That’s it for pom.xml, this is the whole file for reference:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.programmer.gate</groupId>
  <artifactId>SpringBootOAuth2</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Spring Boot OAuth2</name>
  
  <properties>
       <maven.compiler.source>1.8</maven.compiler.source>
       <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>
  
  <dependencies>
  
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security.oauth.boot</groupId>
        <artifactId>spring-security-oauth2-autoconfigure</artifactId>
        <version>2.0.0.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.0.0</version>
    </dependency>
    
  </dependencies>
  <build>
      <plugins>
          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
      </plugins>
  </build>
</project>

3- Create credentials for your webapp

The first thing to do before start integrating OAuth2 into your application is to setup and configure the application in the authority service which will authenticate your users, you could use several authority services like (Facebook, Twitter, Github … ) at the same time but for simplicity we choose to go with Google in this tutorial.

To configure your application in google, follow the below steps:

  • Open Google Console API
  • Click on “New Project” button at the top left of the page.
  • Set a name for your project then click “Create”.
  • Now your application is created, choose your application from the list of projects at the top toolbar, then choose “APIs & Services” -> “Credentials” from the left menu.
  • Click “Create Credentials” -> “OAuth Client Id” then choose your application type, in this tutorial we choose “Web Application”
  • Add your redirect URI under “Authorized redirect URIs” text box, this is the URL which google uses when redirecting back to your application after successful authentication.
  • Click on “Create”.

Now your application is setup and configured under Google and you should get “Client Id” and “Client Secret” which uniquely identifies your application.

4- application.properties

Now go back to your application and configure OAuth2 under application.properties:

# Change default server port and configure view resolver
server.port=9090
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
server.error.whitelabel.enabled=false
 
# OAuth2 configuration
security.oauth2.client.clientId=<CLIENT_ID_GENERATED_IN_PREVIOUS_STEP>
security.oauth2.client.clientSecret=<CLIENT_SECRET_GENERATED_IN_PREVIOUS_STEP>
security.oauth2.client.preEstablishedRedirectUri=http://localhost:9090/callback
security.oauth2.client.accessTokenUri=https://www.googleapis.com/oauth2/v3/token
security.oauth2.client.userAuthorizationUri=https://accounts.google.com/o/oauth2/auth
security.oauth2.client.tokenName=oauth_token
security.oauth2.client.authenticationScheme=query
security.oauth2.client.clientAuthenticationScheme=form
security.oauth2.client.scope=profile
security.oauth2.resource.user-info-uri=https://www.googleapis.com/userinfo/v2/me
security.oauth2.client.useCurrentUri=false

Here we tell our application to redirect to Google authentication page whenever an unauthorized user tries to access the application, as you see we use the “Client Id” and “Client Secret” of our application that we generate from google in the previous step.

We also statically set the redirect URI to be used by Google through “preEstablishedRedirectUri” attribute, the value of this attribute should be defined under the “Authorized redirect URIs” list that we set in the previous step OR you’ll get “Error: redirect_uri_mismatch” on redirection.

P.S: if you don’t define “preEstablishedRedirectUri” attribute, Spring Boot will automatically use “localhost:9090/login” as the redirect URI.

5- Create JSP pages

Our application consists of 2 JSP pages: index.jsp and home.jsp

We define index.jsp to be the root page of the application, anyone could access it without authentication. For simplicity purposes, our page acts as a login page and it just holds a “Login With Google” button which authenticates the user through Google API.

<!DOCTYPE html>
<html>
<head>
</head>
<body>
     <a href="/login">Login with Google</a>
</body>
</html>

And we define home.jsp as the home page which any authorized user reaches after successful authentication with Google.

<!DOCTYPE html>
<html>
<head>
</head>
<body>
      <h1>Congratulations !! You're authorized, this is the home page</h1>
</body>
</html>

Both jsp files are defined under WEB-INF/jsp which we previously defined as a view resolver prefix under application.properties.

6- Override application security

By default, Spring Security doesn’t allow unauthorized users to open any page in the application without a redirection. In order to exclude our index.jsp page from authentication, we override WebSecurityConfigurerAdapter class as the following:

package com.programmer.gate;
 
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
@Configuration
@EnableOAuth2Sso
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .antMatcher("/**")
          .authorizeRequests()
            .antMatchers("/", "/callback", "/login**", "/webjars/**", "/error**")
            .permitAll()
          .anyRequest()
            .authenticated();
    }

In the configure() method, we define specific URLs like (“/”, “/callback”, “/login**”, “/webjars/”, “/error”) to be excluded from Spring authentication through using permitAll() while telling Spring to authenticate any other URL through .antMatcher(“/**”) .authorizeRequests()

The use of @EnableOAuth2Sso is mandatory, this is the annotation which initializes and auto-configures OAuth2, you can use this annotation either in the Spring Boot initializer class or here in the configurer.

7- HomeController.java

Now we define our controller under com.programmer.gate as the following:

package com.programmer.gate;
 
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class HomeController {
    
    @RequestMapping("/")
    public String login() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        System.out.println(auth.getPrincipal());
        return "/index";
    }
    
    @RequestMapping("/callback")
    public String callback() {
        System.out.println("redirecting to home page");
        return "/home";
    }
}

Here we define the root page of our application to be “index.jsp” and we also define the callback method which google redirects to after successful authentication, as you see our callback function would just redirect to “home.jsp”.

8- Application.java

The final step is to create the Spring Boot initializer, this is the entry point of our application. We define Application.java under com.programmer.gate.

package com.programmer.gate;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class Application{
 
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

9- Demo

This is what we get when accessing http:localhost:9090

local host

And this is what we get after clicking on “Login With Google” or when accessing any other URL:

login google

10- Source code

You can download the source code from this repository: spring-boot-oauth2

Summary

In this tutorial we explain how to secure a Spring Boot application using OAuth2.

Next Steps

If you're interested in learning more about the basics of Java, coding, and software development, check out our Coding Essentials Guidebook for Developers, where we cover the essential languages, concepts, and tools that you'll need to become a professional developer.

Thanks and happy coding! We hope you enjoyed this article. If you have any questions or comments, feel free to reach out to jacob@initialcommit.io.

Final Notes