Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement OAuth2 "Token Exchange" with Spring Cloud Security

I would like to know if someone has an example to see how to implement "Token Exchange" technique with Spring Cloud Security (with OAuth2).

Currently I have implemented "Token Relay" technique in a Microservices Environment using ZuulProxy to "relay" the OAuth2 token and implementing SSO. This is great but implies that every microservice uses the same clientId (which is specified in ZuulProxy setup as ZuulProxy relays the token only with authorization_code grant type and the clientId provided). However, for intra-microservices calls I would like to "exchange" the token. This means in some cases the token that ZuulProxy relays is not the one I need to use to authenticate/authorize Microservice A as client of Microservice B.

The Spring Cloud reference documentation currently says: "Building on Spring Boot and Spring Security OAuth2 we can quickly create systems that implement common patterns like single sign on, token relay and token exchange." (http://cloud.spring.io/spring-cloud-security/spring-cloud-security.html)

I guess that with "Token Exchange" in the reference documentation they mean the implementation of this extension of OAuth2, explained in this spec, which is basically what I need: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-token-exchange-03

As I said, I understand how to use SSO and Token Relay but I'm not able to see further explanation about how to implement "Token exchange" in the reference documentation. I was not able to find an implementation example either.

Does anyone know where I can find further information or an example?

Thanks so much!

like image 934
miguelfgar Avatar asked Jan 20 '16 16:01

miguelfgar


People also ask

How is OAuth2 implemented in spring?

We have to set an interface for the authorization server where the user can provide the credentials. We use the formLogin() implementation of Spring Security to achieve that functionality while keeping things simple. We also make sure that all requests are authenticated.

Does Spring Security using OAuth2?

Spring Security handles the Authentication and Spring Security OAuth2 handles the Authorization. To configure and enable the OAuth 2.0 Authorization Server we have to use @EnableAuthorizationServer annotation.

How does OAuth2 2.0 work in spring boot?

Spring Security OAuth2 − Implements the OAUTH2 structure to enable the Authorization Server and Resource Server. Spring Security JWT − Generates the JWT Token for Web security. Spring Boot Starter JDBC − Accesses the database to ensure the user is available or not. Spring Boot Starter Web − Writes HTTP endpoints.


2 Answers

I think this is something you might try.

In my project we also use OAuth2, Eureka, Ribbon for microservices to communicate each other. In order to use Ribbon with OAuth2, the approach we took was bit different.

First we leave the restTemplate untouched.

  @LoadBalanced
  @Bean
  public RestTemplate restTemplate() {

However, we created FeignClientIntercepter implementing RequestIntercepter which sets authorization tokens for OAuth when making a request via restTemplate.

  @Component
  public class FeignClientInterceptor implements RequestInterceptor {

    private static final String AUTHORIZATION_HEADER = "Authorization";
    private static final String BEARER_TOKEN_TYPE = "Jwt";

    @Override
    public void apply(RequestTemplate template) {
      SecurityContext securityContext = SecurityContextHolder.getContext();
      Authentication authentication = securityContext.getAuthentication();

      if (authentication != null && authentication
          .getDetails() instanceof OAuth2AuthenticationDetails) {
        OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication
          .getDetails();
        template.header(AUTHORIZATION_HEADER,
            String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));
      }
    }
  }
like image 71
Ted Kim Avatar answered Oct 17 '22 09:10

Ted Kim


I'm curious why you'd need to "exchange" the token for making calls from Microservice A to Microservice B and why relaying is not sufficient? What are your trying to achieve by exchanging tokens for inter-service requests?

We have a set up very similar to what is described in this Nordic APIs entry. The short version is that external callers use an opaque token, but once the request goes through our gateway, every microservice gets a JWT representation of the same token. We had to implement a custom endpoint to to perform the opaque to JWT exchange. When services need to interact with one another, we do not exchange the token when A needs to call B, we simply relay the token. Either the RestTemplate or Feign client will automatically forward the token from A to B. Thus, context is not lost.

Now, if we wanted to control access, the JWT could specify a collection of audience values or we could enforce access via scopes. We are actually doing a combination of the two depending on the use case.

Exchanging tokens is not a cheap operation, in fact it's quite expensive at scale and should really consider why you need to do a token exchange for intra-service communication. If you every API request is going result in service A calling service B and you have to make a token exchange, you're going to have ensure that your authorization service can handle that type of workload. Lastly, the IETF token exchange is still draft status, and has changed quite a bit in its evolution, so I would not expect much in the way of implementation advice until the spec gets closer to finalization.

like image 20
Ryan J. McDonough Avatar answered Oct 17 '22 10:10

Ryan J. McDonough