1. Overview

This article contains Spring Security OAuth 2.0 Resource Server Example, In our previous article we have configure authentication server , In this article, we will talk about Resource Server Configuration using spring security. Resource Server contains actual resources like RestAPI, Images etc. To access those requires resource server ask for access token which is given by the authentication server.

Complete flow of communicating between Authentication and Resource Server:

1. The user will login in Authentication server using user/password
2. If username/password is valid, Authentication server will return access token and refresh token
3. Using Access token go to Resource Server to access resources.
3.1. Now Resource Server will communicate with an Authentication server to check Access token is valid or not (Internally)
3.2. Authentication server give Acknowledgement, Token is valid or not (Internally)
4. If the token is valid then resource server will give you an actual resource that you requested in Step 3.
5. If the token is invalid then resource server will not allow accessing the resources.

 2. Example

Technology Stack

We have used following frameworks used to build Spring Security OAuth 2.0 Resource Server Example using spring boot

  • Spring boot
  • Spring security
  • Spring auth2.0
  • Maven
  • Tomcat 8.5
Spring Security OAuth 2.0 Resource Server Example

Spring Security OAuth 2.0 Resource Server Example

2.1 pom.xml

<?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>spring-boot-example</groupId>
    <artifactId>spring-security-auth-2.0-resource-server-example</artifactId>
    <version>1.0-SNAPSHOT</version>
    <description>Spring Security Auth 2.0 Resource Server Example</description>
    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>  <!--starter require for spring boot spring security-->
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
    </dependencies>

    <!-- Package as an executable jar -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.2 application.properties

application.properties  must contain details of authentication server URL which is useful when any request comes to access the resource it will check access token is valid or not an authentication server.

security.oauth2.resource.token-info-uri indicate URL of access token check URL

security.oauth2.client.client-id indicate client id

security.oauth2.client.client-secretindicates client secret

server.port=7777
security.oauth2.resource.token-info-uri=${auth-server:http://localhost:8080}/oauth/check_token
security.oauth2.client.client-id=javadeveloperzone
security.oauth2.client.client-secret=secret

2.3 SecurityResourceServerConfig

ResourceServerConfigurerAdapter has been extended which has configure method that contains configuration about which access token is required to access which URL. For example, here we have configured that to access /demo must have read access scope.

RequestDumperFilter is only used to check request log when access token authenticates with the authentication server.

package com.javadeveloperzone;

import org.apache.catalina.filters.RequestDumperFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

/**
 * Created by JavaDeveloperZone on 09-12-2017.
 */

@Configuration
public class SecurityResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/demo")
                .access("#oauth2.hasScope('read')");      // require 'read' scope to access /demo URL
    }
    @Bean
    RequestDumperFilter requestDumperFilter() {
        return new RequestDumperFilter();
    }
}

2.4 SpringBootApplication

Its like other spring boot configuration but must be required@EnableResourceServer which indicate that spring boot application considers as Resource Server.

package com.javadeveloperzone;

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

/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */

@SpringBootApplication
@ComponentScan({"com.javadeveloperzone"})
@EnableResourceServer           // To enable resource server
// Using a root package also allows the @ComponentScan annotation to be used without needing to specify a basePackage attribute
public class SpringBootResourceApplicationConfig {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootResourceApplicationConfig.class, args);            // it wil start application
    }
}

2.5 SpringBootResourceController

package com.javadeveloperzone.controller;

import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */
@RestController
public class SpringBootResourceController {

    @RequestMapping("/demo")
    public String demo(Principal principal) {
        return "Hello "+principal.getName()+", Auth 2.0 Resource Server, Access Granted by authentication server..";
    }
}

2.6 Output:

  1. Access resource with authentication : http://localhost:7777/demo
Spring Security OAuth 2.0 Resource Server Example - Access resource

Spring Security OAuth 2.0 Resource Server Example – Access resource

2.  Access resource for authentication : http://localhost:7777/demo

Spring Security OAuth 2.0 Resource Server Example - Token Expired

Spring Security OAuth 2.0 Resource Server Example – Token Expired

4. References

Spring boot auth2.0 documentation

Was this post helpful?
Let us know, if you liked the post. Only in this way, we can improve us.
Yes
No

11 comments. Leave new

How this application knows the authentication server user/password? In properties we are just mentioning client id and secret only.

Resource server will communicate with the authentication server. Here is an example of the authentication server

Please read both articles. Using an implementation of both two you can implements OAuth2.0.

In the authentication server you are using zone1 and mypassword for accessing it, but in the current example (resource sever) you are not using them..and directly hitting the authentication server with client and secret, how this knows authentication server credentials?

No need of password while access data from the resource server, just token is enough.

Let me explain complete flow:

1. The user will login in authentication server using user/password
2. Authentication server will return access token and refresh token, If username/password is valid
3. Using Access token go to Resource Server to access resources.
3.1. Now Resource Server will communicate with an Authentication server to check Access token is valid or not (Internally)
3.2. Authentication server give Acknowledgement, Token is valid or not (Internally)
4. If the token is valid then resource server will give you an actual resource that you requested in Step 3.
5. If the token is invalid then resource server will not allow accessing the resources.

Now flow is clear why you do not request username and password in resource server.

Got you, but some reason its giving invalid token error even I am passing the correct token and in the console I see “oauth 2 Handling error: InvalidRequestException, Missing grant type”, I have just copied your code, any suggestion?

When are you getting this error while getting token or getting resources?

I mean, Have you able to generate an access token and refresh token from authentication server? now trying to access resources?

Authentication server is working fine, I am able to see all the data access token, refresh tokens. When i copy that access token and hitting the resource, its giving “error”: “invalid_token”, but I am giving the same token and I confirm its valid. In the eclipse console I see “oauth 2 Handling error: InvalidRequestException, Missing grant type”.

I am not sure why you are facing this issue.

Are you sure you have to request to Resource server? I am mean that if you are using Post Man tool then have you update URL of Resource server. I am sorry but I am just guessing from here.

Some points that i like to focus on:

1. Once your Authentication server is restart then all the token will not work after that you need to create another token or persist those token to solve this issue.
2. Make sure that Authentication server is also running while access resources, In short, both server must be running. !!

Yes, I am running both on different ports and as per the error I understood, resource server is able to hit the auth server and giving invalid_token error! I have googled also but no luck :-(. I agree as per the setup this should work, but some reason, its saying invalid token that’s interesting.

Ok. Make sure that you are passing token in the header with Authorization : Bearer [TOKEN]

Leave a Reply

Your email address will not be published. Required fields are marked *