Spring Cloud Gateway routing doesn't work - spring

I'm using Spring Cloud(Hoxton.SR10) with Spring Boot (2.2.6.RELEASE)
I registre my services in Eureka server 8761
and I have a gateway-service to manage routing (without any security for the moment)
# profil DEV
---
spring:
profiles: dev
cloud:
gateway:
routes:
- id: pr-api-id
uri: http://localhost:8086/
predicates:
- Path=/api/**
and this is the pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- Spring cloud eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
when I call localhost:9092/api/v0 (I have a service on localhost:8086/v0 that working fine) should return me the same result of localhost:8086/v0 du to the routing of spring cloud gateway
but I got http error 404
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Sep 27 12:46:20 CEST 2021
There was an unexpected error (type=Not Found, status=404).
No message available
gateway mainClass java
#SpringBootApplication
#EnableEurekaClient
public class GatewayApplication {

I finally resolve my problem by adding the cors-configuration in my config file.
spring:
cloud:
gateway:
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Origin
globalcors:
cors-configurations:
"[/**]":
allowCredentials: true
allowedOrigins: "*"
allowedHeaders: "Origin, X-Requested-With, Content-Type, Accept, Content-Length, TOKEN, Authorization"
allowedMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS"
maxAge: 3628800

Related

Spring Gateway: No provider found for OAuth2AuthorizationCodeAuthenticationToken

looking at stack i cannot find a answer that solves this problem, i am stuck at this. If anyone could help, thank you for advance.
I'm migrating my reverse proxy from zuul to spring cloud gateway (oauth2), i search and read Spring documentation and other topics about this subject but i can't understand what's missing. When i try to get a page, i get the login page from my authentication manager (ok), i enter my user and password (it checks and get 200) and then instead of redirecting to the previous page i get this :
"java.lang.IllegalStateException: No provider found for class org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken
at org.springframework.security.web.server.authentication.AuthenticationWebFilter.lambda$authenticate$4(AuthenticationWebFilter.java:100) ~[spring-security-web-5.1.13.RELEASE.jar:5.1.13.RELEASE]
[...]"
This is my yml for authentication server:
client:
registration:
auth_provider:
client-id: service
client-secret: service-secret
scopes: openid,read,write
authorization-grant-type: authorization_code
redirectUriTemplate: http://localhost:9010/login/oauth2/code/{registrationId}
provider:
auth_provider:
authorization-uri: http://localhost:9010/api/auth_provider/oauth/authorize
token-uri: http://localhost:9010/api/auth_provider/token
user-info-uri: http://localhost:9010/api/auth_provider/oauth/users/extra
And the routes (resume):
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
default-filters:
- TokenRelay
routes:
- id: auth_provider
uri: lb://auth_provider/
predicates:
- Path=/api/auth_provider/**
- id: my_service
uri: lb://my_service/
predicates:
- Path=/ui/my_service/**
This is my Security Configuration (resume):
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
// Require authentication for all requests (allow login screen)
http
.authorizeExchange()
.pathMatchers("/api/auth_provider/**", "/login**", "/login?error**", "/login?logout**", "/logout").permitAll()
.anyExchange().authenticated();
// Authenticate through configured OpenID Provider
http.oauth2Login();
//JWT Resource Server
http.oauth2ResourceServer().jwt();
http.csrf().disable();
return http.build();
}
And the pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- Token Relay -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-security</artifactId>
</dependency>
<!-- http.oauth2ResourceServer().jwt() -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
If anyone have this problemas and could help, thank you very much.

Spring cloud Gateway router always gives 404 error

I have a spring cloud project. This project consists of three main parts: A service discovery with Eureka, A gateway with Spring Cloud Gateway and service for REST API endpoints. I want to define API endpoints like this:
GET
/available
and route them with a path predicate in gateway:
GET
/service-one/available
To achieve this, I've added this route in gateway's yml file:
spring:
cloud:
gateway:
routes:
- id: service_one
uri: lb://service_one
predicates:
- Path=/service-one/**
filters:
- StripPrefix=1
but when I try
// 9000 is the gateway's port number
http://localhost:9000/service-one/available
I get this error:
{
"timestamp": "...",
"path": "/service-one/available",
"status": 404,
"error": "Not Found",
"message": null,
"requestId": "..."
}
More details:
Spring Boot version: 2.4.5
Spring Cloud version: 2020.0.2
Discovery:
pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
application.properties:
server.port=8761
spring.application.name=discovery
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Application startup:
#SpringBootApplication
#EnableEurekaServer
public class DiscoveryApplication {
// ...
}
Gateway:
pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.yml:
spring:
application:
name: gateway
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
httpclient:
wiretap: true
httpserver:
wiretap: true
routes:
##
##
- id: service_one
uri: lb://service_one
predicates:
- Path=/service-one/**
filters:
- StripPrefix=1
##
##
eureka:
client:
register-with-eureka: false
Service:
pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.properties:
spring.application.name=service_one
server.port=8080
eureka.client.register-with-eureka=true
eureka.client.service-url.default-zone=http://localhost:8761/eureka
Service Endpoint:
#SpringBootApplication
#EnableEurekaClient
#RestController
public class ServiceOneApplication {
// ...
#GetMapping("/available")
public String available() {
return "Hi, Service One is available";
}
}

Zuul retry functionality not working after adding all configurations in application.yml

I have a scenario with spring boot, zuul as the gateway, and Eureka as Service discovery. I need to implement the retry mechanism before doing the fallback in the gateway. But the retry code is not working.Applcation.yml is given below
server:
port: 8080
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8083/eureka
spring:
application:
name: gateway-service
zuul:
retryable: true
prefix: /api
routes:
test-service:
sensitive-headers: Cookie,Set-Cookie
service-id: test-service
path: /testservice/**
strip-prefix: true
retryable: true
test-service:
ribbon:
MaxAutoRetries: 5
retryableStatusCodes: 503
OkToRetryOnAllOperations: true
authorization:
token:
name: Authorization
prefix: Bearer
secret: qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
hystrix:
command:
test-service:
execution:
isolation:
strategy: THREAD
thread:
timeoutInMilliseconds: 60000000
timeout:
enable: false
app:
auth:
allowPermissionPaths:
- /
- /error
- /favicon.ico
- /**/*.png
- /**/*.gif
- /**/*.svg
- /**/*.jpg
- /**/*.html
- /**/*.css
- /**/*.sass
- /**/*.js
- /api/testservice/**
the pom.xml adding below
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
I am expecting help to implement the retry with zuul gateway.

Getting unexpected error (type=Method Not Allowed, status=405) error while access /refresh actuator is not working

I created one #RestController class and trying to use /refresh actuator values from config server.
/refresh actuatoris not working. I am getting below error. Spring boot version is 2.0.0-Release. I can not upgrade spring boot version.
http://localhost:8888/secondservice/admin/refresh
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Jan 23 10:16:10 EST 2020
***There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'GET' not supported***
Dependency:-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Foo.Class
#RefreshScope
#RestController
public class Foo {
#Value("${welcome.message}")
private String personName;
#RequestMapping(value ="/", produces = "application/json", method = RequestMethod.POST)
public String greet(){
return "hello " + "POST "+ personName;
}
}
bootstrap.yml
server:
port: 8888
spring:
application:
name: secondservice
cloud:
config:
uri: http://localhost:8890/configserverdemo
fail-fast: false
enabled: true
server:
bootstrap: true
management:
context-path: /admin
security:
enabled: false
endpoints:
web:
exposure:
include: "*"
endpoint:
refresh:
enabled: true
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'GET' not supported
The above error means that HTTP GET is not supported on that particular endpoint.
To refresh the config from spring config server you need to make an HTTP POST request on http://localhost:8888/secondservice/admin/refresh
Below is from the Spring guide
You can invoke the refresh Actuator endpoint by sending an empty HTTP POST to the client’s refresh endpoint
To make the HTTP POST request, you can use any HTTP client, eg Postman or cURL. To use cURL, you can run the below command on a terminal
curl -X POST http://localhost:8888/secondservice/admin/refresh

Properties are not read from Vault on Integrating Vault with Spring Cloud Config Server

I am trying use Spring boot config server with git and vault and all my spring boot client application will retrieve the vault properties via the config server by passing the vault config token.
I am using the spring boot 2.1.8.RELEASE and below is the POM.xml file for my spring boot config server.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.ps.psc</groupId>
<artifactId>psc-config-server</artifactId>
<version>0.0.1</version>
<name>psc-config-server</name>
<description>Spring configuration server</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-monitor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
The bootstrap.yml file
spring:
profiles:
active:
- git
- vault
cloud:
config:
enabled: true
server:
git:
order: 2
username: ********
password: ********
uri: https://*******#bitbucket.org/krushna/configuration.git
search-paths:
- payment*
vault:
host: 127.0.0.1
port: 8200
scheme: http
order: 1
skip-ssl-validation: true
kv-version: 1
vault:
authentication: TOKEN
token: s.PB5cAJ9WhOuWamIOuFVkzpbl
scheme: http
host: 127.0.0.1
port: 8200
config:
order: 1
My application.yml file
server:
port: 7000
spring:
application:
name: configserver
With the above configuartion my config server is able read the properties only from the GIT not from the vault.
In the vault I have written a properties like below.
vault write secret/payment password=test#123
If I make curl call like below
curl -X "GET" "http://127.0.0.1:7000/payment/default" -H "X-Config-Token: s.PB5cAJ9WhOuWamIOuFVkzpbl"
I am geeting properties from git only, response below.
{
"name": "payment",
"profiles": ["default"],
"label": null,
"version": "e9b941d22f6b7cd3083a731d168f78fa4ec0fc42",
"state": null,
"propertySources": [{
"name": "https://******#bitbucket.org/krushna/configuration.git/application.properties",
"source": {
"foofromGit": "bar"
}
}]
}
What I am doing worng here? I have tried multiple option like differnt KV version, only configuring spring cloude config vault etc.
Edit:
I have used the vault conf like below.
backend "file" {
path = "vault"
}
listener "tcp" {
tls_disable = 1
}
and doing curl to vault driectly I am able to read the value now.
curl -X GET -H "X-Vault-Token:s.PB5cAJ9WhOuWamIOuFVkzpbl" http://127.0.0.1:8200/v1/secret/payment/
response:
{
"request_id": "35c8793e-3530-81c1-7917-3e922ef4065b",
"lease_id": "",
"renewable": false,
"lease_duration": 2764800,
"data": {
"password": "test#123"
},
"wrap_info": null,
"warnings": null,
"auth": null
}
I am able to fix the issue by moving the git and spring cloude config vault configuration details from bootstrap.yml to application.yml like below.
bootstrap.yml
spring:
application:
name: configserver
cloud:
vault:
authentication: TOKEN
token: s.jyFarEyroi5pJNOxPnhT4f3D
scheme: http
host: 127.0.0.1
port: 8200
config:
order: 1
Application.yml
server:
port: 7000
spring:
profiles:
active: git, vault
cloud:
config:
server:
git:
uri: https://krushna#bitbucket.org/krushna/configuration.git
search-paths:
- payment*
vault:
port: 8200
host: 127.0.01
skip-ssl-validation: true
scheme: http
I am still not clear how this fix the issues?, only thing I know that bootstrap will load first, and I am reading the git credential from vault and then application.yml has the other details for the spring cloud config vault and git.
Any explanation on this will be really welcome

Resources