1
votes

i'm developing an application with spring boot, spring cloud, and Zuul as gateway.

With Spring Security i created an authorization service which will generate a JWT token when the user login.

The Zuul Gateway can decode this token and let the request go inside my application to the routed services.

The question now is, how can i get the logged user (or the token itself) in one of the microservices? Is there a way to tell the Zuul gateway to attach the token to every request he passes to a routed path?

All the microservices do not have Spring Security as a dependency, because the idea is to check the token only at the gateway level, not everywhere, but i can't find a proper way to do so...

Let's say I have a User Service routed in the gateway. After the login the user wants to check his profile.

He will make a request to {{gateway_url}}/getUser with the token.

The gateway configuration is

zuul:
  ignored-services: '*'
  sensitive-headers: Cookie,Set-Cookie
  routes:
    user-service:
      path: /user/**
      service-id: USER-SERVICE

The gateway will route this request to the USER-SERVICE application, to the getProfile controller method how can i know which is the logged user? Who made the request?

2
The downstream service should get the appropriate HTTP header. - spencergibb
There are no headers in the downstream message... it look like the gateway does not send anything with the request - besmart
What header are you expecting? - spencergibb
The best would be the jwt - besmart

2 Answers

0
votes

The sensitive headers are a blacklist, and the default is not empty. Consequently, to make Zuul send all headers (except the ignored ones), you must explicitly set it to the empty list. Doing so is necessary if you want to pass cookie or authorization headers to your back end. The following example shows how to use sensitiveHeaders:

application.yml:

 zuul:
  routes:
    users:
      path: /myusers/**
      sensitiveHeaders:
      url: https://downstream
0
votes

The question now is, how can i get the logged user (or the token itself) in one of the microservices? Is there a way to tell the Zuul gateway to attach the token to every request he passes to a routed path?

You can add any custom header to the request before zuul routes it, take a look at this code:

@Configuration
public class ZuulCustomFilter extends ZuulFilter {

    private static final String ZULL_HEADER_USER_ID = "X-Zuul-UserId";

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

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication != null && authentication.getPrincipal() != null;
    }

    @Override
    public Object run() throws ZuulException {
        if (
            SecurityContextHolder.getContext().getAuthentication().getPrincipal() != null &&
            SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof OnlineUser
            ) {

            OnlineUser onlineUser = (OnlineUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            RequestContext ctx = RequestContext.getCurrentContext();

            ctx.addZuulRequestHeader(ZULL_HEADER_USER_ID, onlineUser.getId());

        }
        return null;
    }
}

In this sample, the id of the user is attached to the request and then it is routed to the corresponding service. This process takes place right after user authorization performed by spring security