Adding Headers to Zuul when re-directing
Asked Answered
J

5

9

I am trying to use Zuul to redirect calls to a downstream system somewhere else. In the re-direct, I need to add in a Header with necessary data for the api receiving the redirection to process. I can't seem to get the downstream system to detect this data. Attached is my code. I am using Zuul from Edgware.SR3, Spring Boot 1.5.12

Zuul Filter

@Component
public class RouteFilter extends ZuulFilter{

@Override
public Object run() {
//Testing to add header
    context.getRequest().getParameterMap().put("api", new String[]{"api"});
    context.getResponse().setHeader("api", api);
    context.addZuulResponseHeader("api", "api");
    context.addZuulRequestHeader("api", "api");
    context.setSendZuulResponse(false);
    context.put(FORWARD_TO_KEY, redirect_urls.get(key));
    context.setResponseStatusCode(HttpStatus.SC_TEMPORARY_REDIRECT);
    context.getResponse().sendRedirect(redirect_urls.get(key));
    return null;
}
}

Redirected Service Code

@RequestMapping(value = "/forward")
public ResponseEntity<String> forwardToMe(@RequestHeader(required = true, name = "api")String api){
    return new ResponseEntity<String>("Hi",HttpStatus.OK);
}

Error Received in Postman

{ "timestamp": 1524737817729, "status": 400, "error": "Bad Request", "exception": "org.springframework.web.bind.ServletRequestBindingException", "message": "Missing request header 'api' for method parameter of type String", "path": "/forward" }

Jenisejenkel answered 26/4, 2018 at 10:29 Comment(2)
sendRedirect doesn't pass any custom header that you've provided. context.addZuulXXXHeader is just for normal routing.Konstanz
Thanks, I noticed. Thus asking if anyone had better experience manipulating headers in Zuul Redirects.Jenisejenkel
V
5

I guess you use a Route Filter, maybe you can try with a Pre Filter.

Adding a custom header can be done with something like this : context.addZuulRequestHeader("Authorization", "Basic " + credentials);.

For the redirection part, you can check this thread

Vichyssoise answered 27/4, 2018 at 13:5 Comment(3)
I do have a pre-filter setup, and I did add data into the headers similarly as you did in pre-filters. None of the data made it through to the endpoint, works inbetween filters though. I did do a workaround to solve this issue I am facing.Jenisejenkel
Are you able to resolve this issue?? I am also facing same issue.Downstage
@Jenisejenkel what did you do to solve this issue?Rouvin
L
3

A little late my response but works fine
As referred in the official documentation Cookies and Sensitive Headers
The sensitiveHeaders 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:

zuul:
  routes:
    entry:
      path: /users/**
      strip-prefix: false
      service-id: users-service
      sensitive-headers:
      - Cookie,Set-Cookie

This implemented example can also help you

Loella answered 10/4, 2020 at 19:5 Comment(0)
C
2

In case if anyone still facing this issue,

In Zuul Proxy add the header to RequestContext as below:

RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulRequestHeader("param", "value");

And then in the respective microservices write a custom filter and extract the value as below

@Component
public class MyFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response,
                                FilterChain filterChain)
                                throws ServletException, IOException {

        String headerParam  =   request.getHeaders("param").nextElement();
    
        logger.info("headerParam: "+headerParam);
    
        filterChain.doFilter(request, response);
    }

}
Citriculture answered 22/1, 2021 at 4:6 Comment(0)
D
1

I update my comment here just in case if anyone is still facing this problem. I found this problem recently and resolved by adding the following configuration in my application.yml

application.yml ... zuul: sensitive-headers: - Cookie,Set-Cookie ...

Reference Link below:
https://cloud.spring.io/spring-cloud-static/Dalston.SR5/multi/multi__router_and_filter_zuul.html

Doited answered 5/7, 2019 at 1:35 Comment(0)
A
0
RequestContext ctx = RequestContext.getCurrentContext();
    String auth = "useeerrr" + ":" + "passsss";
    ctx.addZuulRequestHeader("Authorization", "Basic " +
            Base64Variants.MIME_NO_LINEFEEDS.encode(auth.getBytes(StandardCharsets.US_ASCII)));
    ctx.addZuulRequestHeader("X-USERNAME-HEADER","xxx");

    Map<String, List<String>> newParameterMap = new HashMap<>();
    Map<String, String[]> parameterMap = ctx.getRequest().getParameterMap();
    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
        String key = entry.getKey();
        String[] values = entry.getValue();
        newParameterMap.put(key, Arrays.asList(values));
    }
   
    String authenticatedKey = "authenticated";
    String authenticatedValue = "true";
    newParameterMap.put(authenticatedKey,Arrays.asList(authenticatedValue));
    ctx.setRequestQueryParams(newParameterMap);
    HttpServletRequest request = ctx.getRequest();

    logger.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));

    return null;
Aureomycin answered 13/11, 2021 at 17:47 Comment(1)
While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.Artificial

© 2022 - 2024 — McMap. All rights reserved.