Zuul request headers not forwarded - spring-boot

I have an application that uses Zuul and is hosted in a Kubernetes Cluster on AWS. It would appear that Zuul is not forwarding headers from the request to the destination, so I m having to do this:
private void copyRequestHeaders() {
RequestContext context = RequestContext.getCurrentContext();
Enumeration<String> headerNames = context.getRequest().getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
context.addZuulRequestHeader(headerName, context.getRequest().getHeader(headerName));
}
}
I'm guessing that I shouldn't have to do this and that I'm missing a configuration option somewhere or something like that. Can anyone shed any light on this. Interestingly the application works fine in my local development environment.
I'd also like to know the purpose of the ZuulRequestHeader and ZuulResponseHeadera and how they differ from standard request and response headers. Are they wrappers perhaps?
Thanks

Try adding the sensitiveHeaders in your configuration.
zuul:
routes:
sample:
sensitiveHeaders:
path: /sample
Removing any values on sensitiveHeaders means that all headers passed on your Zuul Gateway will be passed deep within the microservices.
For more information, refer to this documentation.

By default, Zuul API Gateway will not let sensitive information to be forwarded to downstream Microservices.
The default value for this property is
zuul.sensitiveHeaders: Cookie,Set-Cookie,Authorization
we can override this value to allow certain headers by
zuul.sensitiveHeaders: Cookie,Set-Cookie
And to allow all the headers we can keep it blank
zuul.sensitiveHeaders:

Related

How to redirect to https with Spring cloud gateway & ribbon

I have 2 microservices working with https, I added spring cloud gateway api to centralize the routes but I faced a problem where it says: This combination of host and port requires TLS I'm pretty sure that's because of the routes configuration on my gateway, I dont have much experience on this side but if someone could help me.
this is my spring gateway routes configuration :
#Bean
public RouteLocator gatewayRouter(RouteLocatorBuilder builder){
return builder.routes()
.route(p -> p.path("/api/v1/**")
.uri("lb://statement"))
.route( p -> p.path("/api/v3/**")
.uri("lb://activiti-workflow"))
.build();
}
Please I just want to know if this configuration will redirects to https or not, because while sending http requests directly to the microservices it works but with gateway is doesn't.
If your backend services in eureka provide https, your can set route uri like this:
uri: lb:https://your-service-name
Or
.uri("lb:https://your-service-name")
It just like websocket configuration. The key class is org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter
More info see at: https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-routetorequesturl-filter
If your backend services use insecure HTTPS cert, your may need config this:
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
See at: https://cloud.spring.io/spring-cloud-gateway/reference/html/#tls-and-ssl

Spring cloud gateway proxy to controller in same application

I want to achieve the following with a spring boot webflux application:
I have an endpoint api/test. I would like the same controller to be available on dynamically configured sub paths. E.g. if configured a sub-route "app" then a request to app/api/test should end up in the same controller.
To facilitate this I did the following using a RouteLocatorBuilder:
route(id = "proxy_api_test") {
host(location.host)
path("/${location.route}/api/test/**" )
filters{
filter(setPathGatewayFilter.apply(createSetPathConfig("/api/test")))
}
uri(location.uri)
}
In case of testing on localhost for example location.host would be "localhost:8080" and location.route could be "app" and location.uri would be "http://localhost:8080".
And createSetPathConfig is given as:
fun createSetPathConfig(template: String): SetPathGatewayFilterFactory.Config{
val config = SetPathGatewayFilterFactory.Config()
config.template = template
return config
}
When running the application that would work like a charm because requests to http://localhost:8080/app/api/test would be redirected to http://localhost:8080/api/test with the help of spring cloud gateway. I have chose this approach also because it could be various sub paths at the same time, so the same controller must be available from different entry paths.
Now what I see is that this does not work in unit-tests using an #Autowired val client: WebTestClient because when executing the unit-test in fact no web-server is running. Is there a way to indicate with the uri in with RouteLocatorBuilder that the request should be executed on the same host such that unit-test would also work with the same logic? Because in fact in this case I would like spring cloud gateway not to forward to another host but to just change the routes dynamically.

how to set private endpoint in zuul

how to set private endpoint in zuul?
env: spring, zuul
i'm using
zuul:
routes:
abc:
path: /abc/**
sensitive-headers:
url: http://abc.api.develop.com
in abc service, i want to make private /abc/xyz/1/test.
only it has to be work, when i request directly to http://abc.api.develop.com/xyz/1/test in server. not https://develop.com/abc/xyz/1/test by gateway.
/abc/1, /abc/1/public, /abc/xyz/2/good etc have to be public.
so only one path(/abc/xyz/1/test) is private endpoint.
how to set this?
can anyone help me please?
or any hint?
is zuul setting or is spring security setting?
how to block this specific path?
I used ignoredPatterns: /abc/xyz/*/good.

Handling of requests locally by Zuul Gateway server

How do I make Spring Boot Zuul Proxy Server handle a specific request locally, instead of proxying it to some other Server?
Let's say I want to do a custom health check of Zuul Proxy Server itself through an API which should return a local response, instead of returning a proxied response from some other remote server.
What kind of route configuration is required to forward the request?
Following is what I figured out and it worked for me:
1) Create a local request handler:
Add a regular Controller/RestController with a RequestMapping in a file in Zuul proxy Server code
#RestController
public class LocalRequestHandler {
#GetMapping(path = "/status", produces = MediaType.TEXT_PLAIN_VALUE);
private static ResponseEntity<String> getServiceStatus() {
String status = "I am alive";
return ResponseEntity.ok().body(status);
}
}
2) Create a local forwarding route in the configuration file (application.properties or as the case may be) where other routes are defined. In my case, Spring Boot Zuul Proxy server is running on Jetty container with GatewaySvc as the application context.
zuul.routes.gatewaysvc.path=/GatewaySvc/status
zuul.routes.gatewaysvc.url=forward:/GatewaySvc/status
For a standalone Spring Boot, which I have not tested, you may have to remove the context path from the above configuration.
zuul.routes.gatewaysvc.path=/status
zuul.routes.gatewaysvc.url=forward:/status
Reference:
Strangulation Patterns and Local Forwards

Spring-Cloud Zuul breaks UTF-8 symbols in forwarded multipart request filename

this is first time for me on SO, so please be patient for my first question.
I think i have some kind of configuration problem, but after a day of experiments i'm stuck. Our application is based on Spring-Cloud [Brixton release]. We have configuration like this: Portal (web application serving angular-based web-ui), which has zuul proxy with single route configured to our gateway service, like so:
zuul:
ignoredServices: '*'
prefix: /api
routes:
api-proxy:
path: /**
serviceId: api-gateway
which has another Zuul configured and relays requests to inner bussiness logic services:
zuul:
ignoredServices: '*'
routes:
service1:
path: /service1/**
serviceId: service1
service2:
path: /service2/**
serviceId: service2
All this configuration is working with no problem.
The problem now that i am facing is with file upload multipart requests. To be more precise - those multipart requests, when file to be uploaded has non latin symbols (e.g. ąčęėįš) from UTF-8. When request reaches service which has to deal with #RequestPart MultipartFile file, then file.getOriginalFilename() returns questionmarks in the places of aforementioned symbols. Now, i have tried to directly upload such file to such controller, and filename comes without questionmarks, that is, not broken, which suggests, that some bad interpretation/parsing of multipart request occurs somewhere in Zuul filters, when proxy relays incomming request.
Maybe someone had similar experience with Zuul and can direct me some way to resolve this problem?
I just ran into the same issue myself, and created the following issue:
https://jira.spring.io/browse/SPR-15396
Hopefully this is getting configurable in Spring 4.3.8.
In the meantime, you have to create a bean of type FormBodyWrapperFilter (that overrides the one in ZuulConfiguration). In the constructor, you pass a copy of FormHttpMessageConverter, which extends from FormHttpMessageConverter, and you change the encoding used in FormHttpMessageConverter.MultipartHttpOutputMessage#getAsciiBytes(String) to UTF-8 (you might also want to delete any references to javax-mail, unless you have that on classpath). You need a pretty recent version of Spring Cloud Netflix to do this.
Example:
#Bean
FormBodyWrapperFilter formBodyWrapperFilter() {
return new FormBodyWrapperFilter(new MyFormHttpMessageConverter());
}
Then you create a copy of FormHttpMessageConverter, and change the following method:
private byte[] getAsciiBytes(String name) {
try {
// THIS IS THE ONLY MODIFICATION:
return name.getBytes("UTF-8");
} catch (UnsupportedEncodingException ex) {
// Should not happen - US-ASCII is always supported.
throw new IllegalStateException(ex);
}
}
Still having issues after modifying response even with newer versions
Using spring boot 2.3.8.RELEASE
Managed to fix it by forcing the following spring properties
server.servlet.encoding.force= true
server.servlet.encoding.charset= UTF-8

Resources