Search Tutorials


Spring Boot + OAuth 2 Password Grant - Hello World Example | JavaInUse



Spring Boot + OAuth 2 Password Grant - Hello World Example

OAuth (Open Authorization) is a simple way to publish and interact with protected data.
It is an open standard for token-based authentication and authorization on the Internet. It allows an end user's account information to be used by third-party services, such as Facebook, without exposing the user's password.
When using OAuth2, grant type is the way an application gets the access token. Following are the grant types according to OAuth2 specification-
  • Authorization code grant
  • Implicit grant
  • Resource owner credentials grant
  • Client credentials grant
  • Refresh token grant

Spring Boot Security - Implementing OAuth2

Spring Boot Security - Introduction to OAuth Spring Boot OAuth2 Part 1 - Getting The Authorization Code Spring Boot OAuth2 Part 2 - Getting The Access Token And Using it to fetch data. Spring Boot + OAuth 2 Client Credentials Grant - Hello World Example. Spring Boot + OAuth 2 Password Grant - Hello World Example. Facebook Authentication Using Spring Boot + Spring Social Simple Example.

Video

This tutorial is explained in the below Youtube Video.

In a previous tutorial we had seen the Client Credentials Grant in detail.
In this tutorial we will have a look at password grant. Oauth usually consists of following actors -
  • Resource Owner(User) - 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.
  • Client Application - The machine that needs to be authenticated.
  • Authorization Server - The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization
  • Resource Server - The resource server is the OAuth 2.0 term for your API server. The resource server handles authenticated requests after the application has obtained an access token.
In case of Password grant type the user triggers the client to get some resource. While doing so it passes the username and password to the client. The client then communicates with the authorization server using the provided username, password and also its own clientId and clientSecret to get the access token. Using this access token it then gets the required resource from the resource server.
Spring Boot OAuth2 Password Grant
So 2 calls are required to be made by the client application to get the resource-
  • Call to the Authorization Server to get the token.
    Parameter Value
    grant_type (required) client_credentials
    client_id(required) The client id
    client_secret(required) The client secret key
    username(required) The username of the user
    password(required) The password of the user
  • After getting the token from the authorization server, the client application then needs to use this for getting resource from the resource server.
The real life example of Password grant will be you doing a login to you facebook account using its mobile application. Here the user will have to specify the facebook credentials to the app. Also the app will be having its own client id and client secret.
Spring Boot OAuth2 Facebook Password Grant

Lets Begin?

Authorization Server

Lets first create the Authorization Server which will generate a token for client. Maven Project will be as follows-

Spring Boot OAuth2 Password Grant Maven


In the Maven we need the Spring oauth dependency. Maven will be as follows-
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>boot-oauth2-password-authorization-server</artifactId>
	<version>0.0.1.SNAPSHOT</version>


	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.0.RELEASE</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security.oauth</groupId>
			<artifactId>spring-security-oauth2</artifactId>
		</dependency>
	</dependencies>

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


</project>
Define the Spring Boot Main Application. Here we have defined the vaidateUser API which will validate if the token is valid.
Also we have configured the basic Auth using in memory authentication for username and password.
package com.javainuse;

import java.security.Principal;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableResourceServer
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

	@RequestMapping("/validateUser")
	public Principal user(Principal user) {
		return user;
	}

	@Configuration
	protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter {

		@Override
		public void init(AuthenticationManagerBuilder auth) throws Exception {
			auth.inMemoryAuthentication().withUser("javainuse-user").password("javainuse-pass").roles("USER");
		}

	}
}
Configure the Authorization Server. The @EnableAuthorizationServer annotation is used to configure the OAuth 2.0 Authorization Server mechanism and defines the behaviour of various endpoints when interacting with the authorization server.
package com.javainuse.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

	@Autowired
	private AuthenticationManager authenticationManager;

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.authenticationManager(authenticationManager);
	}

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		clients.inMemory().withClient("javainuse-client").secret("javainuse-secret")
				.authorizedGrantTypes("password").scopes("read", "write");

	}
}

Resource Server

Next create the Resource Server which has the reource to be accessed by the client. Maven Project will be as follows-

Spring Boot OAuth2 Password Grant Maven


In the Maven we need the Spring oauth dependency. Maven will be as follows-
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>boot-oauth2-resource-server</artifactId>
	<version>0.0.1.SNAPSHOT</version>


	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.0.RELEASE</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security.oauth</groupId>
			<artifactId>spring-security-oauth2</artifactId>
		</dependency>
	</dependencies>

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


</project>
Define the Spring Boot Main Application. Configure the Resource Serverusing @EnableResourceServer annotation. It means the service expects an access token in order to process the request. Access token should be obtained from Authorization Server by OAuth 2.0 Client before calling the Resource Server.
package com.javainuse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.bind.annotation.RestController;

@EnableResourceServer
@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}
Define the Controller, to expose API which can be accessed only using valid token.
package com.javainuse.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

	@RequestMapping("/test")
	public String test() {
		return "Hello World";
	}
}
Next define the url of the authorization server to be called by the resource server for verifying the token in the application.yml as follows.
security:
  oauth2:
    resource:
      userInfoUri: http://localhost:8080/validateUser
server:
  port: 9090
Finally start the Authorization Server and the Resource Server.
  • First get the Access Token by making a POST request to localhost:8080/oauth/token
    • Specify the client_id and client_secret in the header using base64 encoding.
      Spring Boot OAuth2 Password Grant - Token
    • Next specify the grant type as Password Grant in body and send the request.
      Spring Boot OAuth2 Password Grant - Token Example
      We get the token as response
  • Get the Resource using the access token received above and making a GET call to localhost:9090/test.
    The token is specified as Authorization Bearer.
    Spring Boot OAuth2 Password Grant Tutorial

Download Source Code

Download it -
Spring Boot + OAuth2 Authorization Server for Password Grant
Spring Boot + OAuth2 Resource Server for Password Grant

See Also

Spring Boot Hello World Application- Create simple controller and jsp view using Maven Spring Boot Tutorial-Spring Data JPA Spring Boot + Simple Security Configuration Pagination using Spring Boot Simple Example Spring Boot + ActiveMQ Hello world Example Spring Boot + Swagger Example Hello World Example Spring Boot + Swagger- Understanding the various Swagger Annotations Spring Boot Main Menu Spring Boot Interview Questions