Spring Cloud Gateway and TokenRelay Filter - spring-boot

I’m trying to migrate JHipster from using Zuul to Spring Cloud Gateway. JHipster uses Eureka to look up routes and I believe I’ve configured Spring Cloud Gateway correctly to look up routes and propagate the access token to them. Here’s my config:
spring:
cloud:
gateway:
default-filters:
- TokenRelay
discovery:
locator:
enabled: true
lower-case-service-id: true
route-id-prefix: /services/
httpclient:
pool:
max-connections: 1000
The problem I’m experiencing is the access token is not sending an Authorization header to the downstream services.
Here's how things were configured with Zuul in my application.yml:
zuul: # those values must be configured depending on the application specific needs
sensitive-headers: Cookie,Set-Cookie #see https://github.com/spring-cloud/spring-cloud-netflix/issues/3126
host:
max-total-connections: 1000
max-per-route-connections: 100
prefix: /services
semaphore:
max-semaphores: 500
I created a pull request to show what's changed after integrating Spring Cloud Gateway.
https://github.com/mraible/jhipster-reactive-microservices-oauth2/pull/4
Steps to reproduce the issue:
git clone -b reactive git#github.com:mraible/jhipster-reactive-microservices-oauth2.git
Start JHipster Registry, Keycloak, and the gateway app:
cd jhipster-reactive-microservices-oauth2/gateway
docker-compose -f src/main/docker/jhipster-registry.yml up -d
docker-compose -f src/main/docker/keycloak.yml up -d
./mvnw
Start MongoDB and the blog app:
cd ../blog
docker-compose -f src/main/docker/mongodb.yml up -d
./mvnw
Navigate to http://localhost:8080 in your browser, log in with admin/admin, and try to go to Entities > Blog. You will get a 403 access denied error. If you look in Chrome Developer Tools at the network traffic, you'll see the access token isn't included in any headers.

I was able to solve this using this answer.
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/services/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/services/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
I also had to add .pathMatchers("/services/**").authenticated() to my security config, which wasn't needed for Zuul. You can see my commit here.

Related

Spring Cloud API gateway not working after deploying it on tomcat

After deploying the gateway war file on tomcat not able to access it.
application.yml file setup
server:
port: 9000
servlet:
context-path: /gateway
spring:
cloud:
gateway:
routes:
- id: mysqlservice
uri: http://localhost:8080
predicates:
- Path= /gateway/mysql/**
filters:
- StripPrefix=1
- id: xyzservice
uri: http://localhost:8080
predicates:
- Path= /gateway/xyz/**
filters:
- StripPrefix=1
- id: lightservice
uri: http://localhost:8080
predicates:
- Path= /gateway/light/**
filters:
- StripPrefix=1
The above configuration works fine when I run it through the normal spring boot JAR file
Ex. http://localhost:9000/gateway/mysql/mysqlapi/test
when it deployed on the tomcat server that time I am not able to access it
Ex. Ex. http://localhost:8080/gateway/mysql/mysqlapi/test
So how can i access it from tomcat server?
You can’t as it is not supported:
Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or when built as a WAR.

How to configure kong-api to communicate other spring Microservice

I am just started with Kong API with One API
I am able to run kong api locally using its official docker image available.
And on other side I am having another Spring-Boot microservice locally running inside same Docker engine.
Problem : What configuration needs in kong api yaml file so that I can connect to my spring-boot microservice ?
My kong -api yaml file
services:
- name: control-service-integration
url: http://localhost:8080/
plugins:
- name: oneapi
config:
edgemicro_proxy: edgemicro_demo_v0
add_application_id_header: true
authentication:
apikey:
header_name: "x-api-key"
upstream_auth:
basic_auth:
username: username
password: password
routes:
- name: control-service-route
request_buffering: false
response_buffering: false
paths:
- /edgemicro-demo-v0
From kon-one api service i am getting always 502 Bad Gateway error.
Let me know if anything information required.
I found the solution for this
in above YAML
services:
- name: control-service-integration
url: http://localhost:8080/
add this value in-front of url section http://host.docker.internal:8080/ after doing lot of trials and errors finally now I am able to connect my app which is running on host.

spring zuul gateway in kubernetes

I am introducing in microservices with spring and kubernetes.
I have gateway services made with spring-cloud-starter-netflix-zuul that works like an apigateway
I define Zull gateway like this:
server:
port: 8080
use-forward-headers: true
security:
basic:
enabled: false
oauth2:
resource:
jwk.key-set-uri: ${OAUTH_KEYSETURI}
spring:
config:
name: proxy-service
application:
name: proxy-service
zuul:
routes:
service-one:
path: /service-one/**
url: http://service-one:8080
serviceId: service-one
service-two:
path: /service-two/**
url: http://service-two:8080
serviceId: service-two
ribbon:
eureka:
enabled: false
eureka:
client:
enabled: false
error:
whitelabel:
enabled: false
But I found some problems, for example, that the requests have a limit per service, so I added the following lines:
zuul:
host:
max-per-route-connections: 100000
max-total-connections: 100000
I want to know. What is the most performant way to integrate spring-zuul with Kubernetes? I have read that it can also be integrated with spring-kubernetes-config, ribbon, and eureka. But doing it is more performant?
Recently I also read about spring-cloud-gateway. What is the difference with this project? Why spring has two gateway projects very similar? Are there differences in performance? Will both be supported in the future? What do you recommend to use?

How to Configure Zuul Multiple instances of one microservice

i'm working in a spring cloud project and i have an eruka service, zull proxy and a microservice with the name defects-service (zull proxy and my defects-service are clients for eurka) and all works fine.
in my zull proxy i have the following configuration :
eureka:
client:
register-with-eureka: true
fetch-registry: true
serviceUrl:
defaultZone: http://localhost:8370/eureka/
instance:
hostname: localhost
zuul:
prefix: /api
routes:
defects-service:
path: /defects-service/**
url: http://localhost:8300
my issue is now i start two instances of my defects-service on diferents ports 8301 and 8302 (registred successfully in eruka service ) but i don't know how to configure my zull proxy to do a load balancing and start redirect requests to my three instances on ports (8300,8301,8302).
note , zull knows only the instance on http://localhost:8300
can anyone please helpe me to resolve this isuue .
Best regards .
Zuul support load balancing out of the box, instead of giving url in your configuration, use serviceId:
zuul:
prefix: /api
routes:
defects-service:
path: /defects-service/**
serviceId: defects-service
the solution of this problem is by using the following config :
zuul:
prefix: /api
routes:
defects-service:
path: /defects-service/**
serviceId: defects-service
after that if you got any error like Hystrix Readed time out.. just add the following config :
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 11000
ribbon:
ConnectTimeout: 10000
ReadTimeout: 10000

Dockerized Spring boot and Zuul

I got troubles get Zuul working with a dockerized Spring boot app.
It seems Zuul is not able to proxy requests to the target application (gis_import_export) even if it is up and running.
My Zuul based Spring app configuration:
spring:
banner:
location: classpath:banner.txt
zuul:
debug:
request: true
routes:
ie:
url: http://gis_import_export:8080
geoserver:
url: http://geoserver:8080
geonetwork:
url: http://geonetwork:8080
ribbon:
eureka:
enabled: false
and my docker-compose.yml file:
version: "3"
services:
geoserver:
image: kartoza/geoserver
geonetwork:
image: geonetwork
postgres:
image: postgres
environment:
- POSTGRES_DB=xxx
- POSTGRES_PASSWORD=xxx
- POSTGRES_USER=xxx
gis_import_export:
image: gis_import_export:develop
ports:
- 8888:8080
zuul:
image: gis_api_gateway:develop
ports:
- 8080:8080
I'm able to have geonetwork/geoserver proxied correctly via Zuul service exposed port but I'm stuck with getting with Spring boot app seems not get proxied.
By the way, the dockerized Spring boot apps works as expected if accessed via the 8888 port and via Zuul if zuul itself is not deployed via Docker.
Running a ping/telnet to dockerized spring boot app inside the Zuul docker container works as expected, so names are being resolved correctly.
Ideas?
Thanks, FB
Your services running in different docker networkds.
You have to specify same network in two files network.
And of course it will be good if you specify hostname parameter for each container

Resources