I am using spring cloud gateway for our application. We have a requirement to remove all the sensitive headers from all the configured routes. I have configured it as follows -
spring:
cloud:
gateway:
default-filters:
#Remove All the sensitive request headers (Cookie, Set-Cookie & Authorization) while passing request to downstream services
- RemoveRequestHeader=Cookie
- RemoveRequestHeader=Set-Cookie
- RemoveRequestHeader=Authorization
This is working as expected. Now we have requirement to pass Authorization header to only one of the routes. Is there a way to configure this so that I don't have to add 3 RemoveRequestHeader in all the routes?
I have tried to add Authorization request header specifically for one route but it is not working because of ordering of routes. Once the request headers are removed, these can't be re-added.
P.S. - We were using Zuul before migrating to spring cloud gateway & it was possible to do this.
Default filters are all or nothing. To do what you want you need to add the RemoveRequestHeader to each route that needs it, omitting it from those that don't.
Related
I have a scenario in an implementation of spring cloud gateway (Just for illustration call that service custom api gateway). In this 'Custom API Gateway' I want to define a route, filters, predicate and forward the request to a custom endpoint in the 'custom api gateway'? Is there a way to achieve that? Everything works except forwarding to a URI in the 'custom api gateway'
Here is an example
id: UpdateUser
uri: SHOULD NOT GO DOWNSTREAM (endpoint is in 'custom api gateway')
predicates:
- path=/api/users
filters:
- ValidateSession
Thanks Segi
You can define some controllers in spring cloud gateway and write routes to route requests to these controllers, but you should add uri changing filters like prefixPath, stripPrefix to change uri part to different one.
If you don't change the uri, requests will cause a 413 request entity too large error code, if you open debug level log, you'll see gateway is passing this request over and over again to itself.
I have few services written in Node that are using "X-Request-Id" as the header to identify requests. I am now writing services in Java using spring-boot where I can use spring-cloud-sleuth to track traceId and spanId.
However, I would like to continue using the "X-Request-Id" as the request identifier across all of my services. Is there any way to rename the "X-B3-TraceId" header in spring-sleuth so that it sends the same header in HTTP requests and also uses the said header from incoming requests to set the traceId?
You can propagate extra fields, see the Propagation section of the Spring Cloud Sleuth docs.
spring:
sleuth:
propagation-keys: x-correlation-id
I have two projects. Both are reactive Spring. Project one is a combination of a Javascript application and Spring Cloud Gateway for reverse proxying. The second project is a Spring resource server.
Project one proxies requests from /api/artists to project two at http://localhost:8081/v1/artists.
If I call the resource server (project two) directly with a valid JWT, the response comes back HTTP 200. If I go by way of the reverse proxy in project one, and hit http://localhost:8080/api/artists with the same JWT, I receive an HTTP 403 from project two, which propagates back through project one.
Here is my Spring Cloud Gateway configuration:
spring:
cloud:
gateway:
routes:
- id: experience-api
uri: http://localhost:8081/v1/artists
predicates:
- Path=/api/artists/**
filters:
- TokenRelay=
The HTTP 403 indicates that while the token was valid, it must be lacking some other permission to perform the action. Though, I'm not sure why it works when I call it directly versus calling it by way of the reverse proxy/Spring Cloud Gateway.
After stepping away for a couple days, I realized that my gateway configuration was incorrect. I realized that the original configuration was proxying requests to /v1/artists/api/artists, which doesn't exist on project two, but my security configuration was set up so that /v1/** required authentication. I suspect that is why I saw an HTTP 403 Forbidden before I saw an HTTP 404 Not Found.
I ended up using the below configuration:
spring:
cloud:
gateway:
routes:
- id: experience-api
uri: http://localhost:8081
predicates:
- Path=/v1/artists/**
filters:
- TokenRelay=
Note that I removed /v1/artists from the uri property. Now, requests to project one at http://localhost:8080/v1/artists are getting proxied to http://localhost:8081/v1/artists. I could have used the StripToken predicate filter but it wasn't as clean as this.
I am trying to access a microservice endpoint through a gateway using jhipster. The end point is from a legacy system and starts with "/d" and cannot be modified. I want the gateway to route all the requests that start with '/d/** ' to my microservice where I have a rest controller that will handle the requests that is mapped to '/api/d/**'
I'm trying to work using the documentation, so I have in my gateway the route:
zuul:
routes:
my-service-route:
path:/d/**
serviceId: serviceName
I saw that using url in zuul configuration you can specify the url directly, but I use jhipster registry so I can't approach the problem like that. As far as I understand I have to write a custom Zuul Filter or a Zuul Route Configuration that will route the requests to my service.
So I have 2 problems:
I can't access the gateway if I use a rest that begins with /d
I can't route the requests to my microservice in the way that I expect:
/d/service to be routed to my microservice where I have a restcontroller with a mapping to "/d/service".
Any info on how I should approach this is highly appreciated.
Thanks.
EDIT:
I already added my path in WebConfig source.registerCorsConfiguration("/d/**", config); and in SecurityConfiguration .antMatchers("/d/**").authenticated()
Can you try this below configuration in application.properties also you can change it to yml accordingly. so any request coming as /d/* will redirect to serviceName application instance.
zuul.routes.serviceName.serviceId=serviceName
zuul.routes.serviceName.path=/d/**
zuul.routes.serviceName.sensitive-headers=Set-Cookie,Authorization
hystrix.command.serviceName.execution.isolation.thread.timeoutInMilliseconds=600000
I was trying to search, but did not find an answer suited to our situation.
Basically, we have zuul server as API gateway which does following responsibilites
+ Autheticate user, and create and maintain session with users
+ Sessions will be stored in redis (we are using spring session with redis)
I want to have all of resource servers having access to session information created by zuul server. But I could not get session information from resource servers. its alway return null, I have checked redis server and seen session is created by zuul server already
Note that we are using Netflix service discovery to forward request from Zuul respective service.
highly appreciate for any advice
actually I was missing the following code.
context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId());
After adding above code to pass session_id in the cookie from zuul filter to respective micro-services, it is able to pickup the session_id from zuul filter.
I had the same problem. But after I have configured the application.yml to set "sensitiveHeaders" to empty. My problem is solved! :)
zuul:
routes:
users:
path: /myusers/**
sensitiveHeaders:
url: https://downstream
you can see more details at this link
Even though you're storing session in Redis, session id is stored in cookie and must be delivered to your resource servers. But the default configuration of zuul is filtering out all cookie related headers.
The below is default configuration of zuul for senstive-headers those are not passed to downstream servers.
zuul.sensitiveHeaders=Cookie,Set-Cookie,Authorization
To pass cookie related headers from zuul to your resources servers, You need to redefine it without cookie related headers like belows.
zuul.sensitiveHeaders=Authorization
The above example is using global configuration. You can define it for each route. Please refer to the section "Cookies and Sensitive Headers" in the the linked doc : http://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html
If you also need to authorization header in your resources servers, you can define above configuration with blank list.
make sure your are using filter more than 5
#Override
public int filterOrder() {
return 10;
}
for more detail find the below example
https://stackoverflow.com/a/54833734/11103297
When using Spring Session and Spring Security to protect APIs in a Microservice application, it is easy to set up to use the request header to resolve the session, the usage is very similar to the OAuth2 opaque token.
Declare a bean HttpSessionIdResolver.
HeaderHttpSessionIdResolver.xAuthToken()
Note: this is for Spring MVC. It will resolve the HTTP header x-auth-token.
When a request is sent from client, in the gateway, pass the header x-auth-token to the downstream services/components.
An working example: hantsy/spring-microservice-sample (But I did not use Zuul like Gateway in this sample application, and simply I used Nginx as reserve proxy)