1
votes

I have been trying to build a spring distributed application that works on JWT. Github repo - https://github.com/dhananjay12/spring-microservice-demo

Service Description

  • product-service : A simple downstream service having protected routes
  • jwt-resoure-server : A jar that when included in downstream services make it a resourceserver that extract jwt token and set it in security contex.
  • eureka-service : Discovery service
  • zuul-server : Edge server
  • Okta is my auth server

I have set oauth grant type to be - Authorization code (I know for spa implicit grant type is recommended but lets say due to some constraint in future we are restricted to this grant type)

So angular client after successfully login, auth server revert back to the angular app with authorization code like :

http://localhost:4200/?code=iTJkTvXfESQFvGJmio_l&state=my-state

Now I have to hit auth server with this code to get the access and id token.

Since this requires client secret, I have to pass it through zuul (as only back-end service can have client secrets), which should add client_secret to the body and forward the request to auth server.

I am struggling with this last part. Any insights? Tried creating a TokenFilter, but its not working for post request. https://github.com/dhananjay12/spring-microservice-demo/tree/master/zuul-server/src/main/java/com/mynotes/microservice/zuulserver

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

import java.io.IOException;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class TokenFilter extends ZuulFilter {

    @Autowired
    private OauthConfiguration oauthConfiguration;

    @Override
    public int filterOrder() {
        return 6;//PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        if (request.getRequestURI().contains("/token")) {
            return true;
        }
        return false;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        request.setAttribute("client_secret", oauthConfiguration.getClientSecret());

        System.out.println(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
        return null;
    }
}
1
Why do you say implicit grant type is recommended over authorization code? AC provides more security, the advantage of implicit grant is only in terms of net traffic (quite slight), AFAIK. Also I don't understand the last part. From my point of view, the flow should be now to either attach the client secret to the code, either in the server or in the JS (why should zuul do it?).Xtreme Biker
Client secret can only be at server. Are you suggesting that I have another service written to talk to my auth server (currently its okta) for these tokes? I thought there might be a way in zuul as it already has the client secret and all it needs to do is route the request after appending the cleint_secret.Dhananjay
In my opinion it should be the application (the one behind keycloak), which knows its client secret, the one requesting the access token. If zuul does that, you're making zuul the client, which is not bad at all, but, what if you need to put another application behind it? digitalocean.com/community/tutorials/…Xtreme Biker

1 Answers

0
votes

You'll need to use a redirect that saves the code from the authorization code call. Then you'll need to use this saved code to make a call to the token endpoint to get the access token.

Something like this:

zuul:
  routes:
    auth/code:
      path: /auth/code/**
      sensitiveHeaders:
      url: auth end point
    auth/token:
      path: /auth/token/**
      sensitiveHeaders:
      url: token end point
    auth/redirect:
      path: /auth/redirect/**
      sensitiveHeaders:
      url: base url

This article explains the above in further details.