Spring Cloud Gateway with OAuth2 Authorization Server

In this article I will create a Spring Cloud Gateway application connected to an OAuth2 Authorization Server. I will use an existing OAuth2 Authorization server and create a Spring Cloud Gateway application from scratch to consume data from a Resource Server.

Content

  • OAuth2 protocol
  • API Gateway
  • Spring Cloud Gateway
  • Security Token

Check this video for more details.

All the code of the article is available in the following repository.

OAuth2 protocol

I’ve already made an article about creating a complete authorization server with OAuth2 and OpenID. Today, I will leave the same structure but only change the client as a Sprint Cloud Gateway application.

In the OAuth2 authentication protocol, there are three main components: the Client Server, the Authorization Server and the Resource Server. The Authorization Server is the one which checks the credentials. The Resource Server is the one which contains data. The Authorization Server knows the Resource Server and it gives its protection. Everybody who wants to access the data of the Resource Server must be authorized by the Authorization Server. Finally comes the client. This one must be registered and accepted on the Authorization Server. This will create trust between the Authentication Server and the Client Server.

API Gateway

The Authorization Server and the Resource Server are generally big applications, consumed by multiple clients. I would rather work on the client application than develop an Authorization Server. If I’m building a simple application, a simple monolith application, I can use the OAuth2 client dependency with little configuration, check here how to do it.

But if I’m working on a big application, on a microservice architecture, I will definitely have an API Gateway in front of my application. The API Gateway allows me to redirect the incoming requests to the internal microservices having no logic in the API Gateway, only redirection rules. This way, each microservice will have its own logic and there is no necessity to have a master microservice which knows about the other micorservices. But the API Gateway is the only entry point to my microservice architecture. This means that it’s the main responsible for the security. As my application is built on top of the Spring Cloud and Spring Boot dependencies and I don’t own the Authorization Server neither the Resource Server, I must adapt my existing application to consume those servers.

I’m already aware that when calling the Authorization Server a login page will be returned. This is fine when everything is done from the browser. But what about using it from a backend API? Or from a mobile app? I just need the frontend to read the adequate headers, as location, redirect, to correctly display the login page. It can be widescreen or in an iframe.

Spring Cloud Gateway

So let’s create my Spring Cloud Gateway application.

<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-gateway</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-oauth2-client</artifactId>
		</dependency>
	</dependencies>

With the Gateway application, all will be done in the configuration file. Let’s create it.

spring:
  application.name: backend-gateway-client
  cloud:
    gateway:
      routes:
        - id: resources
          uri: http://backend-resources:8082/messages
          predicates:
            Path=/messages/**
  security:
    oauth2:
      client:
        registration:
          gateway:
            provider: my-provider
            client-id: gateway-client-id
            client-secret: my-secret
            authorization-grant-type: authorization_code
            redirect-uri: "http://backend-gateway-client:8083/login/oauth2/code/{registrationId}"
            scope: openid, message.read
        provider:
          my-provider:
            issuer-uri: http://backend-auth:8081

The first part, from line 3, is dedicated to the routes, to requests other microservices. The second part, from line 10, is dedicated to the OAuth2 connection.

Every time the Client Server receives a request on the /messages endpoint, the Gateway will call the Resource Server at the /messages endpoint. Nothing more. This is just a plain redirection.

In the second part, I can see the OAuth2 client configuration. At lines 16 and 17 are the client-id and the client-secret stored in the Authorization Server. At line 20 are the scopes the gateway will request against the Authorization Server. At line 19 I have the redirection URL after the authentication is successful. This is a standard URL in the OAuth2 protocol. And finally, at line 23, where to locate the Authorization Server.

Security Token

Okay. Now, I have the Authorization Server which has the client registered. On the other side, my Gateway is configured to authenticate against the authorization server and route the request to the resource server. Nevertheless, the resource server must know that any incoming request is validated by the authorization server. For that, I have to use the following filter.

spring:
  cloud:
    gateway:
      routes:
        - id: resources
          uri: http://backend-resources:8082/messages
          predicates:
            Path=/messages/**
          filters:
            TokenRelay=

What is the TokenRelay filter for? Spring Gateway will forward any incoming security token from the request to the destination. Once the client is authenticated through the Authorization Server, it will use a security token in its request. This token will be now forwarded to the resource server. And this token will be used by the Resource Server to trust the request.

Conclusion

  • I was using an existing Authorization Server and Resource Server which don’t belong to me.
  • I registered my client into the Authorization Server to obtain the client-id and client-secret.
  • I create my client with the dependencies Spring Gateway and OAuth2 client.
  • I configured the routing to request the resource server.
  • I configured the OAuth2 protocol with the URL of the Authorization Server, the client-id and the client-secret.
  • And finally, add the TokenRelay filter which will forward the security tokens from the client server to the resource server.

Links

Repository

My New ebook, How to Master Git With 20 Commands, is available now.

Leave a comment

A WordPress.com Website.