spring

Spring Security OAuth2 Example

In this article we will learn how to integrate OAuth2 with Spring Security.

1. Introduction

Spring Security is a powerful and highly customisable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. It is a framework that focuses on providing both authentication and authorisation to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements. It provides protection against attacks like session fixation, clickjacking, cross site request forgery, etc.

 
In the traditional client-server authentication model, the client requests an access-restricted resource (protected resource) on the server by authenticating with the server using the resource owner’s credentials. In order to provide third-party applications access to restricted resources, the resource owner shares its credentials with the third party. This creates several problems and limitations:

  • Third-party applications are required to store the resource owner’s credentials for future use, typically a password in clear-text.
  • Servers are required to support password authentication, despite the security weaknesses inherent in passwords.
  • Third-party applications gain overly broad access to the resource owner’s protected resources, leaving resource owners without any ability to restrict duration or access to a limited subset of resources.
  • Resource owners cannot revoke access to an individual third party without revoking access to all third parties, and must do so by changing the third party’s password.
  • Compromise of any third-party application results in compromise of the end-user’s password and all of the data protected by that password.

OAuth addresses these issues by introducing an authorisation layer and separating the role of the client from that of the resource owner. In OAuth, the client requests access to resources controlled by the resource owner and hosted by the resource server, and is issued a different set of credentials than those of the resource owner.

Instead of using the resource owner’s credentials to access protected resources, the client obtains an access token — a string denoting a specific scope, lifetime, and other access attributes. Access tokens are issued to third-party clients by an authorisation server with the approval of the resource owner. The client uses the access token to access the protected resources hosted by the resource server.

1.1 OAuth

The OAuth 2.0 authorisation framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. The OAuth 2.0 specification replaces and obsoletes the OAuth 1.0 protocol.

OAuth defines four roles:

resource owner: An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.

resource server: The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.

client: An application making protected resource requests on behalf of the resource owner and with its authorisation. The term “client” does not imply any particular implementation characteristics (e.g., whether the application executes on a server, a desktop, or other devices).

authorisation server: The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorisation.

2. Example

The example we will follow is described in Spring Boot and OAuth. In this section we create a minimal application that uses Facebook for authentication. This will be quite easy if we take advantage of the auto-configuration features in Spring Boot.

2.1 Creating new project

In this section we will see how to create a simple spring based project. Go to the parent folder where you want to create the application. On the command line run mvn archetype:generate . This will generate a new project from an archetype. If the project is fully generated, it is generated in a directory corresponding to its artifactId. Just press enter when it ask you to ‘Choose a number or apply filter’ and ‘Choose org.apache.maven.archetypes:maven-archetype-quickstart version:’. Then you need to provide the groupId, artifactId, version and package. You can then import that project into your favourite IDE.

2.2 Add a Home page

In your new project create an index.html in the “src/main/resources/static” folder. You should add some style sheets and java script links so the result looks like this:

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <title>Spring OAuth Demo</title>
    <meta name="description" content=""/>
    <meta name="viewport" content="width=device-width"/>
    <base href="/"/>
    <link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css"/>
    <script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
    <script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<h1>Spring OAuth Demo</h1>
<div class="container"></div>
</body>
</html>

None of this is necessary to demonstrate the OAuth2 login features, but we want to have a nice looking UI in the end, so we might as well start with some basic stuff in the home page. If you start the app and load the home page you will notice that the stylesheets have not been loaded. So we need to add those as well, and we can do that by adding some dependencies:

pom.xml

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>2.1.1</version>
</dependency>
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>3.2.0</version>
</dependency>
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>webjars-locator-core</artifactId>
</dependency>

We added Twitter bootstrap and jQuery (which is all we need right now). The other dependency is the webjars “locator” which is provided as a library by the webjars site, and which can be used by Spring to locate static assets in webjars without needing to know the exact versions (hence the versionless /webjars/** links in the index.html). The webjar locator is activated by default in a Spring Boot app as long as you don’t switch off the MVC autoconfiguration. With those changes in place we should have a nice looking home page for our app.

2.3 Securing the application

To make the application secure we just need to add Spring Security as a dependency. If we do that the default will be to secure it with HTTP Basic, so since we want to do a “social” login (delegate to Facebook), we add the Spring Security OAuth2 dependency as well:

pom.xml

<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>

To make the link to Facebook we need an @EnableOAuth2Sso annotation on our main class:

App.java

@SpringBootApplication
@EnableOAuth2Sso
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

and some configuration:

application.yml

security:
  oauth2:
    client:
      clientId: 233668646673605
      clientSecret: 33b17e044ee6a4fa383f46ec6e28ea1d
      accessTokenUri: https://graph.facebook.com/oauth/access_token
      userAuthorizationUri: https://www.facebook.com/dialog/oauth
      tokenName: oauth_token
      authenticationScheme: query
      clientAuthenticationScheme: form
    resource:
      userInfoUri: https://graph.facebook.com/me

The configuration refers to a client app registered with Facebook in their developers site, in which you have to supply a registered redirect (home page) for the app. This one is registered to “localhost:8080” so it only works in an app running on that address.

With that change you can run the app again and visit the home page at http://localhost:8080. Instead of the home page you should be redirected to login with Facebook. If you do that, and accept any authorisations you are asked to make, you will be redirected back to the local app and the home page will be visible. If you stay logged into Facebook, you won’t have to re-authenticate with this local app, even if you open it in a fresh browser with no cookies and no cached data. (That’s what Single Sign On means.)

The app you just wrote, in OAuth2 terms, is a Client Application and it uses the authorization code grant to obtain an access token from Facebook (the Authorization Server). It then uses the access token to ask Facebook for some personal details (only what you permitted it to do), including your login ID and your name. In this phase facebook is acting as a Resource Server, decoding the token that you send and checking it gives the app permission to access the user’s details. If that process is successful the app inserts the user details into the Spring Security context so that you are authenticated.

If you look in the browser tools (F12 on Chrome) and follow the network traffic for all the hops, you will see the redirects back and forth with Facebook, and finally you land back on the home page with a new Set-Cookie header. This cookie (JSESSIONID by default) is a token for your authentication details for Spring (or any servlet-based) applications.

3. Conclusion

In this article we saw how to develop an application using Spring Boot and OAuth. In the first section we discussed what is Spring Security and how easy it is to configure it in Spring Boot (for basic purpose). In the next section we discussed about OAuth. In section 2 we discussed how to configure all bits and pieces to achieve the desired result.

4. Download the Source Code

Download
You can download the full source code of this example here: spring-oauth-example

Mohammad Meraj Zia

Senior Java Developer
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button