Spring Cloud Gateway route to itself - spring

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.

Related

Spring Cloud Gateway - Remove Request Headers from All the routes but one

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.

Is it possible to create a proxy controller that ignores some part of the URI

I have a spring service with multiple controllers with following request mapping running on port 9000
/api/fruits
/api/vegetables
/api/plants
Given all these requests are being served at localhost:9000,is it possible via some Spring entity, that a request to localhost:9000/{Account_id}/api/fruits is routed to localhost:9000/api/fruits. I know the question is a little vague but I'm trying to see if I can add a proxy controller with mapping /{account_id}/ which ignores the rest of the uri and have some code there to forward it to the appropriate controller. Not sure if Spring interceptor or filter of some sort would be helpful here for me to modify the request and change the URI

Spring cloud oauth 2 with ingress kubernetes

Is it possible to use spring cloud oauth 2 server with kubernetes api gateway ingress.
I have used it with zuul to authenticate user before making a call. Can I do similar with ingress?
Edit 1:
To explain it more clearly, what I am trying to achieve
I am using token based oAuth2 implementation given by the spring cloud.
oauth is running as one of the service behind the zuul.
zuul has routes mapped for the oauth server and resource server
client call the auth server via zuul and gets the token.
client call resource server via zuul with token passed
zuul is configured to validate the token before making a call to resource server.
In this way we can stop any downstream traffic to go without a valid token.
can we do token validation in ingress with auth server running with in a cluster?
I have not used Spring Cloud OAuth 2 but as OAuth is a standard I believe you can set it up if you are using Nginx Ingress as the ingress controller, you can specify and external Oauth Provider (As OAuth generally has the same flow) like this on your ingress:
...
metadata:
name: application
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
...
You can find more information here with an example of using GitHub as an OAuth provider
There are currently three different nginx-ingress-controllers (see here), which differ in functionality. I believe that none of these ingress controllers themselves can perform an oauth token introspection. However, requests can be routed to the authorization server's introspection interface using the auth_request module.
Specifically for your case, you can use the auth-url annotation (see) in the ingress controller to direct the requests to the introspection interface of the spring cloud oauth2 server (see). The introspection interface is available under /oaut/check_token by default when #EnableAuthorizationServer is used. If the introspection interface returns a 2XX, the ingress will forward the request. This functionality is based on the auth_request module, which expects a 2xx response code from the external service if the access is allowed and 401 or 403 if denied.
If you use JWTs and want to validate the request by only checking the signature, this can in some cases actually be done by the ingress itself. To my knowledge, only the nginx plus ingress controller (paid) can validate JWTs. But there is also the nginx-based kong-ingress controller, which you can equip with pulgins (see here). There is e.g. promoted with oauth2 integration and JWT validation.
Did you find out more than me?

Zuul routing in microservices

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

how to use spring gateway in a cloudfoundry routing service

We would like to use Spring Cloud Gateway to implement a CloudFoundry Route Service.
In short: every request coming in to the 'Route Service' needs to be forwarded to a url defined as a Request Header (X-CF-Forwarded-Url). The request can be modified/blocked by the 'Route Service' id required.
From what I see (and as the name implies) Spring Cloud gateway is only able to proxy a request. Is it possible to do something like that?
Why 'Spring Cloud Gateway'? I think it provides a very nice API and lots of thoughts have gone into it. It also just feels as a very related usecase/extension to the whole API.

Resources