navigation

Configuring Google as OAuth2 authorization provider in Spring Boot

Configuring Google as OAuth2 authorization provider in Spring Boot

by
July 28, 2015

Recently we have decided to give modern look and feel of our product wish.dreamix – a collective fundraising HR tool allowing employees in a company to improve the surrounding work environment. We know UI and UX of a web platform is a must have feature and led by the desire of RAD (Rapid Application Development) we have chosen a technology stack which consists of AngularJS + Material Design for the Front-End and Spring Boot for the Back-End.

As the title of the blog describes we are going to focus on the back-end and specifically authentication and authorization of resources with OAuth2 protocol using Spring Boot. If you want to get more familiar with how Spring Boot uses the OAuth2 check this very interesting blog post from @david_syer – Senior Engineering Consultant at PivotalThere are many articles, describing how to achieve this type of security, but configuring the framework to work with Google as authorization provider is not so straightforward due to Bearer Token header authorization request issue. I will describe how to solve it later in the article, but first let’s set up the global picture.

I assume you have already prepared a Spring Boot application project. If not, you can use http://start.spring.io/ which is very convenient web tool to initialize a project with multiple checkboxes representing different dependencies. If you are heading to use this approach make sure to include OAuth2 and Cloud Security from the Cloud dependencies. If you are setting up the project manually and you are using Maven as a build tool, make sure your pom file includes the following lines:

<dependency>
			<groupId>org.springframework.security.oauth</groupId>
			<artifactId>spring-security-oauth2</artifactId>
			<version>2.0.7.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-security</artifactId>
			<version>1.0.2.RELEASE</version>
		</dependency>

 

At the time I am writing this blog post these are the latest versions of the libraries.

Spring Security OAuth2 provides standard Spring and Spring Security programming models and configuration idioms for using OAuth2 protocol. Spring Cloud Security in combination with Spring Security OAuth2 will allow us to quickly create an application that implement common patterns like single sign on, token relay and token exchange.

As I said at the beginning of the blog post we have chosen Spring Boot framework, because we wanted to rebuild our product fast and in the same time to make it stable and easy to scale. Just with one annotation and a small amount of configuration we can add SSO feature to our project. Here is our main application class:

package eu.dreamix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.security.oauth2.sso.EnableOAuth2Sso;

@SpringBootApplication
@EnableOAuth2Sso
public class WishApplication {

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

The configured application.yml file: 

spring:
  oauth2:
    client:
      clientId: 123
      clientSecret: xxx
      accessTokenUri: https://www.googleapis.com/oauth2/v3/token
      userAuthorizationUri: https://accounts.google.com/o/oauth2/auth
      clientAuthenticationScheme: query
      scope: profile email
    resource:
      userInfoUri: https://www.googleapis.com/plus/v1/people/me
      preferTokenInfo: false

+

package eu.dreamix.configuration;

import org.springframework.http.client.ClientHttpRequest;
import org.springframework.security.oauth2.client.DefaultOAuth2RequestAuthenticator;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.common.OAuth2AccessToken;

public class GoogleOAuth2Authenticator extends DefaultOAuth2RequestAuthenticator {

@Override
	  public void authenticate(OAuth2ProtectedResourceDetails resource,
	          OAuth2ClientContext clientContext, ClientHttpRequest request) {
	    OAuth2AccessToken accessToken = clientContext.getAccessToken();
	    String tokenType = OAuth2AccessToken.BEARER_TYPE;
	    request.getHeaders().set("Authorization", String.format("%s %s", tokenType, accessToken.getValue()));
	  }
}
Second, create a class which implements UserInfoRestTemplateCustomizer:
package eu.dreamix.configuration;
import org.springframework.cloud.security.oauth2.resource.UserInfoRestTemplateCustomizer;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;

public class CustomOAuth2RestTemplate implements UserInfoRestTemplateCustomizer {

	@Override
	public void customize(OAuth2RestTemplate template) {
		// TODO Auto-generated method stub
		template.setAuthenticator(new GoogleOAuth2Authenticator());
	}
}
Finally, create an instance of the CustomOAuth2RestTemplate in your main application class:
package eu.dreamix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.security.oauth2.sso.EnableOAuth2Sso;

import eu.dreamix.configuration.CustomOAuth2RestTemplate;

@SpringBootApplication
@EnableOAuth2Sso
public class WishApplication {

UserInfoRestTemplateCustomizer customOauth2Template = new CustomOAuth2RestTemplate;

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

As a conclusion, I want to say that if you need fast time-to-market withоut compromising the quality and in the same time easy maintainability and scalability, you should consider the usage of Spring Boot.

I expect your questions in the comments below. What do you think  about this method and the mentioned tool?

Boyko Dimitrov

Java Developer at Dreamix

More Posts - Website

Follow Me:
TwitterLinkedInGoogle Plus

Do you want more great blogs like this?

Subscribe for Dreamix Blog now!

  • Thanks for the tutorial. How to protect certain resources?

  • Anonymous

    Could you response on above question. I have the same problem. Extending WebSecurityConfigurerAdapter does not well with this configuration

    • Thanks for the interest, guys. Boyko is not available right now, but be sure that he will write as soon as he`s back.

  • Anonymous

    Thanks, I am waiting for the response :)

  • Baki

    Hi Boyko,

    Great aticle! I have one question : if I do everything what you wrote authenticate() method never gets called! Is it enough to just instantiate CustomOAuth2RestTemplate in the main class as UserInfoRestTemplateCustomizer customOauth2Template = new CustomOAuth2RestTemplate()? What effect does it have?

  • Good material. However, I wonder if there is a way to do the same without using SpringBoot.
    Thanks in advance.

  • Hey, I am not able to find out where the Redirect-URI is mentioned in above code…

    Please note that I am totally new to spring boot and trying to implement SSO with google…

  • Srinivas

    Hi Byoko,We are not using the spring boot on the client side
    web application and using the spring 4.x. Can you please help me if you
    have any idea on the manual spring xml configuration which equivalent of @EnableOAuth2Sso