Configuring Multiple JPA Entity Managers In Spring Boot

This blog will demonstrate how to setup multiple entity managers in Spring to connect to different data sources. The solution here also supports Spring Data.

Update Maven Pom file

Include Spring Boot dependency for Spring Data:


Disable DataSourceAutoConfiguration

Since we are setting up the data sources, disable the auto configuration in Spring Boot

@EnableAutoConfiguration (exclude = {  DataSourceAutoConfiguration.class })
public class Application {

Configure Primary Entity Manager

Below is the Java configuration for the primary entity manager

@Profile("!test")          // 1
@EnableJpaRepositories(basePackages = "", entityManagerFactoryRef = "entityManager", transactionManagerRef = "transactionManager")        // 2
public class PrimaryMysqlDBConfiguration {
     @Bean(name = "dataSource")      // 3
     @ConfigurationProperties(prefix = "primary.datasource.mysql")
     public DataSource mysqlDataSource() {
          return DataSourceBuilder.create().build();
    @PersistenceContext(unitName = "primary")   // 4
     @Bean(name = "entityManager")
     public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
          return builder.dataSource(mysqlDataSource()).persistenceUnit("primary").properties(jpaProperties())
     private Map<String, Object> jpaProperties() {
          Map<String, Object> props = new HashMap<>();
          props.put("hibernate.ejb.naming_strategy", new SpringNamingStrategy());
          return props;


  1. @Profile annotation to use this configuration only for non test profile. This allows me to set a different datasource, e.g. H2, when running tests.
  2. @EnableJpaRepositories is used for Spring Data. Note we are using the default transaction manager setup in Spring
  3. Bean for primary datasource. The @ConfigurationProperties annotation specifies the prefix of the properties to use by this datasource. For the example here, the file should include properties like below:
    # DB Connection
  4. Persistence unit name should be setup in the EntityManager bean as shown here.

Configure Secondary Entity Manager

Configuration of the secondary entity manager is very similar to that of the primary.The only thing is we have to define a new transaction manager. Make sure a different prefix is set in the configuration properties of the data source. Also, a different persistent unit name should be used.

@EnableJpaRepositories(basePackages = "", entityManagerFactoryRef = "secondaryMySqlEntityManager", transactionManagerRef = "secondaryTransactionManager")
public class SecondaryMysqlDBConfiguration {
      @ConfigurationProperties(prefix = "secondary.datasource.mysql")
       public DataSource mysqlDataSource() {
            return DataSourceBuilder.create().build();
      @PersistenceContext(unitName = "secondary")
      @Bean(name = "secondaryMySqlEntityManager")
      public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
           return  builder.dataSource(mysqlDataSource()).properties(jpaProperties()).persistenceUnit("secondary").packages("").build();
      @Bean(name = "secondaryTransactionManager")
       public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
             JpaTransactionManager tm = new JpaTransactionManager();
             return tm;
       private Map<String, Object> jpaProperties() {
             Map<String, Object> props = new HashMap<>();
            // naming strategy to put underscores instead of camel case
            // as per auto JPA Configuration
            props.put("hibernate.ejb.naming_strategy", new SpringNamingStrategy());
            props.put("", "update");
            return props;

Note the setup above assumes the primary and secondary data sources are not used together in a single transaction. Hence we can use 2 independent transaction managers.

Specify which Entity Manager to use

Finally, make sure that you specify the name of the secondary transaction in the spring @Transactional annotation:

@Transactional(value = "secondaryTransactionManager")

Also, add the @PersistenceContext annotation with the unit name as defined in the configuration when injecting entity managers;

 @PersistenceContext(unitName = "secondary")
 private EntityManager entityManager;

That’s it!

Validating Spring MVC Request Mapping Method parameters

This short post demonstrates how to set up and use JSR-303 Validation for the arguments in Spring MVC request mapping methods for path variable and request parameter arguments. I am using Spring Boot v1.2.5 with Maven 3.

I. MethodValidationPostProcessor

The only configuration needed is adding the MethodValidationPostProcessor (javadoc) bean to the Spring configuration, e.g.

 public MethodValidationPostProcessor methodValidationPostProcessor() {
      return new MethodValidationPostProcessor();

II Add validation to controller request mapping method

First, add the @Validate annotation to the controller class as follows:

public class HelloController {

Then add any JSR-303 validation annotation to a request mapping method arguments:

 public String sayHi(@Size(max = 10, min = 3, message = "name should have between 3 and 10 characters") @PathVariable("name") String name) {
      return "Hi " + name;

The example codes above shows how to validate a value in the request path marked by @PathVariable. You can do the same with @RequestParam

III Validation exception handling

A ConstraintViolationException will be thrown if the size of the path variable is not within 3 to 10 characters. You may need to catch this exception and process it using a Spring MVC exception handler, for example to return the error messages in the response:

 @ExceptionHandler(value = { ConstraintViolationException.class })
 @ResponseStatus(value = HttpStatus.BAD_REQUEST)
 public String handleResourceNotFoundException(ConstraintViolationException e) {
      Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
      StringBuilder strBuilder = new StringBuilder();
      for (ConstraintViolation<?> violation : violations ) {
           strBuilder.append(violation.getMessage() + "\n");
      return strBuilder.toString();

Using Netflix servo to monitor Java applications

Netflix servo is a lightweight API for exposing and publishing application metrics. This blog will demonstrate step by step how to use servo in a Java application.

Project set up

I use Maven so the first step is to include the following in the pom file:


Adding Metrics to JMX

Adding metrics with servo is simple. For example, the following codes add metrics to a Rest controller for a single end point (/sayhi):

public class TestController {

 @Monitor(name = "requestCounter", type = DataSourceType.COUNTER, description = "Total number of requests", level = DataSourceLevel.INFO)
 private final AtomicInteger requestCounter = new AtomicInteger(0);
 @Monitor(name = "aGauge", type = DataSourceType.GAUGE, description = "A random gauge", level = DataSourceLevel.CRITICAL)
 private final AtomicInteger aGauge = new AtomicInteger(0);
 private final TagList tags = BasicTagList.of("id", "testController", "class", "");
 public void init() {
      Monitors.registerObject("testController", this);
 @RequestMapping(value = "/sayhi", method = RequestMethod.GET )
 public String sayHi(@RequestParam String to) {
      requestCounter.incrementAndGet(); // increment counter
      aGauge.set(RandomUtils.nextInt(0, 100)); // set some random value
      return "hi " + to;

Two metrics are defined in this class using the @Monitor annotation. There are 3 types of monitors: counter, gauge and informational. Note also the user of @MonitorTags annotation. This is used to add a set of tags as key-value pairs to all the annotated fields in the class. In the example above, two key-value pairs with key “id” and “class” and values “testController” and “” respectively.

The object needs to be registered with a monitor registry for it to be monitored. This is done with the following line:

Monitors.registerObject("testController", this);

The registerObject method of the class Monitors use the default monitor registry class DefaultMonitorRegistery to register an object. By default, a JMXMonitorRegistry is used.

To update the monitors, use their corresponding API methods:

 requestCounter.incrementAndGet(); // increment counter
 aGauge.set(RandomUtils.nextInt(0, 100)); // set some random value

Now the metrics are available in JMX and can be viewed via JConsole or VisualVM.

Publishing to other sources

Servo provides a simple and yet powerful API for collecting and publishing metrics to other sources. This makes it easy to add monitors to a Java application and expose them to external monitoring system such as Stackdriver and AWS CloudWatch. The following method setup a metrics poller to collect all metrics regularly (once a minute) and publish to the included metric observers.

 private void initMetricsPublishing() {
      PollScheduler scheduler = PollScheduler.getInstance();
      MetricObserver logObserver = new LoggerMetricObserver("logger-observer"); 
      MetricObserver logObserverRate = new LoggerMetricObserver("logger-observer-rate");
      MetricObserver transform = new CounterToRateMetricTransform(logObserverRate, 1, TimeUnit.MINUTES);
      PollRunnable task = new PollRunnable(
           new MonitorRegistryMetricPoller(),
           logObserver, transform);
      scheduler.addPoller(task, 1, TimeUnit.MINUTES);

Note the poller is associated with two MetricObserver instances logObserver and logObserverRate. The later is wrapped by a CounterToRateMetricTransformer which is used to transform any counter values in the observer into rates.


This is the interface servo uses to publish metrics to. Servo provides a few example implementations, include one for AWS CloudWatch. The following implements a metric observer that logs some metric information

public class LoggerMetricObserver extends BaseMetricObserver {
 private Logger logger = LoggerFactory.getLogger(getClass());

 public LoggerMetricObserver(String name) {
 public void updateImpl(List<Metric> metrics) {
      Preconditions.checkNotNull(metrics, "metrics");
      try {
         for (Metric m : metrics) {
    "{}: name[{}] tags[{}] value[{}]", new LocalDateTime(m.getTimestamp()), m.getConfig()
 .getName(), m.getConfig().getTags(), m.getValue());
       } catch (Throwable t) {
              throw Throwables.propagate(t);

Running the Application

The complete source codes can be found in here. Running the web application (embedded Tomcat) and sending requests to http://localhost:8080/sayhi?to=Raymond with the browsers should display on the console something like the below every minute:

2015-08-04 23:48:10.119 INFO 952 --- [PollScheduler-3] a.c.m.b.servo.LoggerMetricObserver : 2015-08-04T23:48:10.119: name[requestCounter] tags[class=TestController,COUNTER,id=testController,INFO] value[3]
2015-08-04 23:48:10.119 INFO 952 --- [PollScheduler-3] a.c.m.b.servo.LoggerMetricObserver : 2015-08-04T23:48:10.119: name[aGauge] tags[class=TestController,GAUGE,id=testController,CRITICAL] value[51]
2015-08-04 23:48:10.120 INFO 952 --- [PollScheduler-3] a.c.m.b.servo.LoggerMetricObserver : 2015-08-04T23:48:10.119: name[requestCounter] tags[class=TestController,RATE,id=testController,INFO] value[0.04987697014032054]
2015-08-04 23:48:10.120 INFO 952 --- [PollScheduler-3] a.c.m.b.servo.LoggerMetricObserver : 2015-08-04T23:48:10.119: name[aGauge] tags[class=TestController,GAUGE,id=testController,CRITICAL] value[51]

Note the log messages for the 2 metric observers.

Using Spring 4 Condition To Control Bean Registration

Spring 4 introduces the Condition interface which supports a condition to checked and registers a bean only when the condition is matched. In this blog, I will demonstrate how to implement a custom condition interface which will register beans when the active profiles match a regex defined in the condition. This would be useful, for example, to inject mock beans when testing while using the actual implementations at deployment. The classes implemented here is a slight modification of the standard @Profile annotation and supporting classes.


First we define the interface @ProfileRegex as follows

@Target({ElementType.TYPE, ElementType.METHOD})
public @interface ProfileRegex {
      * The profile regex for which the annotated component should be registered.
      String value();

The interface requires a String value attribute which define the regex to use to match the spring context’s active profiles. Note the use of @Condition annotation to define the class that implements the Condition interface, i.e. ProfileRegexCondition.


The class ProfileRegexCondition implements the Condition interface

class ProfileRegexCondition implements Condition {

 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
       Environment environment = context.getEnvironment();
       if (environment != null) {
            String[] profiles = environment.getActiveProfiles();
            MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(ProfileRegex.class.getName());
           if (attrs != null) {
                for (Object value : attrs.get("value")) {
                     for (String profile : profiles) {
                          boolean matches = Pattern.matches((String) value, profile);
                          if (matches) {
                             return true;
                return false;
      return true;

The Condition interface has only one method matches() which determines whether the condition is matched. In our implementation, it iterates all the active profiles and return true if the profile matches the regex as defined in the value of the @ProfileRegex annotation.


Suppose we want to register a mock bean for unit testing. We could define the following bean configuration class

public class TestConfiguration {
     MyService myServiceMockBean() {
         return mock(MyService.class);

Note the use of @ProfileRegex annotation to only register the beans when the active profile matches the regex “test”.  Also, the @ProfileRegex annotation can also be applied to the individual @Bean method to provide a more fine control over bean registration. The following configuration class does the opposite of the above and registers whenever the active profiles does not match the regex “test”.

public class ServiceConfiguration {

    MyService myServiceBean() {
         return new MyServiceImpl();

Below is the unit test to verify the correct (mock) bean is registered

@SpringApplicationConfiguration(classes = TestConfiguration.class)
public class ServiceConfigTest {
    private ApplicationContext context;

    public void testProfileRegexCondition() {
         MyService service = context.getBean(MyService.class);
         assertThat(service, CoreMatchers.notNullValue());
         assertThat(new MockUtil().isMock(service), equalTo(true));

Finally, Spring Boot provides a number of useful conditional annotations under the package org.springframework.boot.autoconfigure.condition. See the javadoc for more details.

Query MongoDB using the Java Driver

In this blog I will demonstrate how to get start with MongoDB Java Driver with examples on how to execute some common queries to the database.

Set up

I use Spring Boot (v1.2.1) with Maven for my project setup and include the following Maven dependency


My MongoDB server is on version 2.6

Example Document

For the rest of this blog, I will use the following example document

    "firstname" : "John",
    "lastname" : "Smith",
    "fullname" : "John N Smith"
    "age" : 25,
    "qualifications" : [
        "Master of Science",
        "B. Eng"

Exact Match

The Java driver API implements a query as a DBObject which is then used as an input to the Collection’s find method for executing a query. The query DBObject can be constructed using a BasicDBObjectBuilder. The following codes demonstrate how to find all documents within a collection with field name “firstname” with value “John”.

 BasicDBObjectBuilder builder = BasicDBObjectBuilder.start().add("firstname", "john");
 DBObject query = builder.get();
 DB db = mongoClient.getDB("mydb");
 DBCursor cursor = db.getCollection("myCollection").find(query);
 List<DBObject> dbObjects = cursor.skip(5).limit(100).toArray();

Note the 5 and 100 in the last line to indicate the first and the maximum number of records to return by the cursor.


To perform like query as in relational database, you have to use regular expression when building the query DBObject using BasicDBObjectBuilder. For example,

BasicDBObjectBuilder builder = BasicDBObjectBuilder.start()
                              .add("fullname", Pattern.compile("john"));

will return documents with fullname “john smith” and “lee john” etc.

Greater Than &/or Less Than

To query with greater than or less than, create a DBObject using $gt(e) and $lt(e).

To get documents with age greater than 18:

BasicDBObjectBuilder builder = BasicDBObjectBuilder.start()
                               .add("age", new BasicDBObject("$gt", 18));

To get documents with age less than 50:

BasicDBObjectBuilder builder = BasicDBObjectBuilder.start()
                              .add("age", new BasicDBObject("$lt", 50));

To get documents with age between 18 and 50 (exclusive):

BasicDBObjectBuilder builder = BasicDBObjectBuilder.start()
                            .add("age", new BasicDBObject("$lt", 50).append("$gt", 18));

Match Value in Array

To query for all documents with matching element in array. For example to find all persons with qualification “B. Eng.”

 BasicDBObject in = new BasicDBObject("$elemMatch", new BasicDBObject("$eq", "B. Eng."));
 BasicDBObjectBuilder builder = BasicDBObjectBuilder.start().add("qualifications", in);

Combining query criteria

The BasicDBObjectBuilder can be used to combine multiple query criteria together, for example

 BasicDBObjectBuilder builder = BasicDBObjectBuilder.start()
                                .add("firstname", "john")
                                .add("age", new BasicObject("$gt", 18))

Custom Json Serializer and Deserializer for Joda datetime objects

This post demonstrates how to add custom Json serializer and deserializer classes for Joda datetime objects when used with Jackson JSON processor. I use LocalDateTime in the examples here but the same approach applies to other joda date(time) classes.

Default Serialization

By default, Jackson serializes the whole joda object as is. For example, consider the following object:

 public class ExampleDto {
      private LocalDateTime asDefault =;

Serializing it with Jackson with

import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper(); 
String json = mapper.writeValueAsString(new ExampleDto());

will return something like below in the json string:


Not really useful

LocalDateTimeSerializer / LocalDateTimeDeserializer

Jackson provides an alternative for handling Joda objects. For example

public class ExampleDto {
       @JsonSerialize(using = LocalDateTimeSerializer.class)
       @JsonDeserialize(using = LocalDateTimeDeserializer.class)
       private LocalDateTime asArray =;

This will return an array of integer representing the datetime in the json string, for example:


Custom Serializer and Deserializer

It is also possible to customize the output json by adding custom serialization and deserialization classes. For example, to generate json like:


The above format is useful when you have to persist the Json in NoSQL database such as MongoDB for datetime queries. To achieve this, first modify the @JsonSerialize and @JsonDeserialize annotations with the names of custom classes and then implements the custom classes:

public class ExampleDomain {
      @JsonSerialize(using = CustomLocalDateTimeSerializer.class)
      @JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
      private LocalDateTime custom =;

Class CustomLocalDateTimeSerializer

public class CustomLocalDateTimeSerializer extends StdScalarSerializer<LocalDateTime> {

      private final static DateTimeFormatter DATE_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd");
      private final static DateTimeFormatter TIME_FORMAT = DateTimeFormat.forPattern("HH:mm:ss");
      public CustomLocalDateTimeSerializer() {

      protected CustomLocalDateTimeSerializer(Class<LocalDateTime> t) {

      public void serialize(LocalDateTime value, JsonGenerator jgen, SerializerProvider prov      ider) throws IOException, JsonProcessingException {
            jgen.writeStringField("date", DATE_FORMAT.print(value));
            jgen.writeStringField("time", TIME_FORMAT.print(value));

Class CustomLocalDateTimeDeserializer

public class CustomLocalDateTimeDeserializer extends StdScalarDeserializer<LocalDateTime> {
      private final static DateTimeFormatter DATETIME_FORMAT = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");

      public CustomLocalDateTimeDeserializer() {

      protected LocalDateTimeDeserializerMongoDb(Class<?> vc) {

      public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
           String dateStr = null;
           String timeStr = null;
           String fieldName = null;
           while (jp.hasCurrentToken()) {
                JsonToken token = jp.nextToken();
                if (token == JsonToken.FIELD_NAME) {
                     fieldName = jp.getCurrentName();
                } else if (token == JsonToken.VALUE_STRING) {
                     if (StringUtils.equals(fieldName, "date")) {
                          dateStr = jp.getValueAsString();
                     } else if (StringUtils.equals(fieldName, "time")) {
                          timeStr = jp.getValueAsString();
                     } else {
                          throw new JsonParseException("Unexpected field name", jp.getTokenLocation());
                } else if (token == JsonToken.END_OBJECT) {
           if (dateStr != null && timeStr != null) {
                  LocalDateTime dateTime = LocalDateTime.parse(dateStr + " " + timeStr, DATETIME_FORMAT);
                  return dateTime;
         return null;

Note how the JsonParser is used in the deserializer. Also, the datetime formats used in the serializer and deserializer must match.

Implementing OAuth2 with Spring Security

I would share my notes on understanding how to set up Spring Security to implement OAuth2. My ultimate goal is to implement an authority provider (Authorization Server in OAuth2 terminology) to support multiple microservices. In this post, I will describe step by step on how to setup Spring Security with OAuth2 and demonstrate how a web server client should interact with the Oauth2 servers.

OAuth2 Roles

OAuth2 consists of the following “roles”:

  1. User / Resource Owner – an entity capable of granting access to a protected resource.
  2. Resource Server – server hosting the protected resources, capable of accepting and responding to protected resource requests using access token
  3. Client – An application making requests to protected resources on behalf of the owner. It can be a web app server, a mobile app, or a client side (e.g. javascript) application.
  4. Authorization Server – Server issuing access tokens to client after successfully authentication the resource owner and obtaining authorization.


  1. Many common servers, e.g. Facebook, Google APIs, implement both the Authorization and Resource Servers.
  2. Depending on the type of clients, the interaction with the OAuth2 servers varies. This blog will focus on a web server client. Aaron Parecki’s blog post provides a concise description of OAuth2 and the interactions required by various client applications

Spring Security OAuth2 Configuration

The codes used in this blog post are largely taken from the sample here, with some minor additions/changes.

Authorization Server

The codes to configure an authorization server are shown below.

public class Application {

 private static final String RESOURCE_ID = "blog_resource";

 public static void main(String[] args) {, args);

 @EnableAuthorizationServer // [1]
 protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

      private AuthenticationManager authenticationManager;

      @Override // [2]
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

      @Override // [3]
      public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
           // @formatter:off
           .scopes("read", "trust")
           .authorizedGrantTypes("client_credentials", "password")
           // @formatter:on



  1. The convenient annotation @EnableAuthorizationServer is used. The server is customized by extending the class AuthorizationServerConfigurerAdapter which provides empty method implementations for the interface AuthorizationServerConfigurer. See the javadoc here for more information.
  2. By default, the authorization server does not secure the authorization end point (/oauth/authorize). The configure method here injects the Spring Security authentication manager (set up in @EnableWebSecurity as in normal Spring Security)
  3. The configure method here setup the clients that can access the server. An in memory client detail service is used here for demo purpose.

Resource Server

The codes to configure a resource server are shown below

 @RequestMapping("/") //[1]
 public String home() {
      return "Hello World";

 @EnableResourceServer // [2]
 protected static class ResourceServer extends ResourceServerConfigurerAdapter {

      @Override // [3]
      public void configure(HttpSecurity http) throws Exception {
           // @formatter:off
           // Just for laughs, apply OAuth protection to only 2 resources
           .anyRequest().access("#oauth2.hasScope('read')"); //[4]
           // @formatter:on

      public void configure(ResourceServerSecurityConfigurer resources) throws Exception {



  1. For testing purpose, a resource end point is included here
  2. Like the Authorization Server, the convenient annotation @EnableResourceServer is used with a bean that extends ResourceServerConfigurerAdapter. See javadoc here for more details
  3. The configure method shows how to setup resources for OAuth2 protection.
  4. Spring Security’s expression based support is used here, i.e. #autho2.hasScope(). An expression handler is registered by default by @EnableResourceServer.

Web Server Client

Now with the OAuth2 servers setup, we can demonstrate how a web server client can access protected resource on behalf of the end user via OAuth2. It consists of the following sequence of interactions:

  1. Client redirects user to the authorization server. User login and approve client access to the resource
  2. Authorization server redirects back to client with the access code
  3. Client exchange the access code with an access token from the authorization server
  4. Client uses the access token to get resource from  the resource server

I won’t have a client web server implemented here but will use a chrome rest client plugin to issue the requests to the oauth2 servers. You may use curl to send the equivalent requests.

Also, for the following to work, you will need to setup normal Spring Security and have a login page so that the end user can login with his credential at the oauth2 server so that he can approve the client for accessing the resource on his behalf. For example, as shown in the codes here.

1: Client redirects user to the authorization server. User login and approve client access to the resource

The client redirects the user to the following URL:


Running the above on your browser should redirect it to the oauth2 server’s login page. Once the user enters and submits his username and password, The OAuth approval page should display as below. I will need to work out how to customize this page later…


2: Authorization server redirects back to client with the access code

When the user clicks “Approve”, the authorization server will redirect back to the client url as defined in the redirect_url parameter of the original request, together with an authorization code, i.e.


Since we don’t have a client server implemented,  the above will cause browser error. But we do now has the authorization code from the authorization server.

3: Client exchange the access code with an access token from the authorization server

Now the client has to exchange the access code with the authorization server for an access token by the following:

POST http://localhost:8080/oauth/token
Header: Authorization: Basic Y2xpZW50LXdpdGgtcmVnaXN0ZXJlZC1yZWRpcmVjdDpzZWNyZXQxMjM=
Payload: grant_type=authorization_code&code=3X42jv

Note that base authorization is set up by default with the @EnableAuthroizationServer annotation for the token endpoint. The string “Y2xp…M=” is the Base64 encoded text of the client’s id and password of the form <client_id>:<client_secret>, i.e.  client-with-registered-redirect:secret123. Ignoring this header will result in the oauth2 server returning an “Full authentication is required to access this resource” error. 

The authorization server should return something like below:

     access_token: "cd515d9d-56b1-4ef6-ae99-317d8975f292     token_type: "bearer     expires_in: 43199 
     scope: "read"

4: Client uses the access token to get resource from  the resource server

With the access token, the client can now get the resource on behalf of the user. Remember we set up 2 toy resources to be protected under oauth2 when setting up the resource server? Let’s try go get hold of it

GET http://localhost:8080/ 
Header : Authorization: Bearer cd515d9d-56b1-4ef6-ae99-317d8975f292

It should return “Hello World” in the response body.

That’s it. We finally got the resource after all these interactions!

A few words on grant type

The client here uses authorization code grant type. As demonstrated above, this means the authorization code is obtained using the authorization server as an intermediate between the client and the resource owner. Note the resource onwer’s credential is never shared with the client. Also, the access token is passed directly from the authorization server to the ciient without going through resource owner’s user-agent, adding a level of security.

You may notice the authorization server config also includes a client my-client-with-secret with grant type client_credentials. This is intended for the client to get access token for accessing its own account. For example:

POST http://localhost:8080/oauth/token
Header: Authorization: Basic bXktY2xpZW50LXdpdGgtc2VjcmV0OnNlY3JldA==
Payload: grant_type=client_credentials

Another interesting grant type is implicit, which is intended for client-side (e.g. browse) client.

Wrap Up…for now

That’s it for now. OAuth2 is a flexible protocol and this article only describe a rather simple but hopefully typical use of it in securing web resources. Also, most of Spring Security support for OAuth2 is not explored here. I wish to cover both in future posts.