Spring Gateway: No provider found for OAuth2AuthorizationCodeAuthenticationToken - spring

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.

Related

How can I use client_credentials to access another oauth2 resource from spring cloud gateway

I want to use client credentials flow to access an OAuth protected resource from spring cloud gateway
There is no authentication needed to hit the gateway end point
The resource is OAuth2 protected and I have to use client credentials flow
Based on the matching PATH and HEADERS the request will be redirected to the corresponding service using cloud gateway routes in props file
I need to get the OAuth token from an Auth service and pass the bearer token in the call to the protected resource
Observations:
The token end point is not called for a token
I am getting 403 Forbidden error from the protected resource
I have tried many solutions provided in stackoverflow but I am not able to resolve the issue. What am I missing here?
Configuration file:
spring:
main.web-application-type: reactive
security:
oauth2:
client:
registration:
my-app:
client-id: client-id
client-secret: client-secret
authorization-grant-type: client_credentials
provider:
my-app:
token-uri: https://xxxxxxxx.com/oauth2/token
SecurityConfig:
#EnableWebFluxSecurity
public class SecurityConfig {
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
return http.oauth2Client().and().build();
}
#Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService) {
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
ReactiveOAuth2AuthorizedClientProviderBuilder.builder().clientCredentials().build();
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
#Bean
public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
return WebClient.builder().filter(oauth).build();
}
}
App:
#SpringBootApplication(
exclude = {
SecurityAutoConfiguration.class
})
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
POM:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
<version>4.1.72.Final</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.0.1</version>
</dependency>
</dependencies>

Spring Cloud Gateway routing doesn't work

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

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.

Spring Security + AAD: invalid_token_response follow-up with latest available spring-boot version (2.1.2)

I am facing the same issue as posted in the question Spring Security + AAD: invalid_token_response
I did try 2.1.0, it didn't help.
I am currently using Spring-boot 2.1.2, spring-security-oauth2-client 5.1.3 and i am still getting the same error
I am sharing my pom.xml
<?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 http://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.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>perdict</groupId>
<artifactId>ouath2-client</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>ouath2-client</name>
<build>
<finalName>predictouath2client</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<properties>
<java.version>1.8</java.version>
<azure.version>2.1.2</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-active-directory-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</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-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth.boot/spring-security-oauth2-autoconfigure -->
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
and the WebSecurityConfig looks like:-
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(oidcUserService);
}
the application.yaml looks like:-
spring:
security:
oauth2:
client:
registration:
azure:
client-id: xxxxxxxxxxxxxxxx
client-secret: xxxxxxxxxxxxxxxx
client-authentication-method: basic
authorization-grant-type: authorization_code
redirect-uri-template: '{baseUrl}/login/oauth2/code/{registrationId}'
scope: openid, https://graph.microsoft.com/user.read
client-name: Microsoft Azure
client-alias: azure
provider:
azure:
authorization-uri: https://login.microsoftonline.com/xxxxxxxxxxxxxx/oauth2/authorize
token-uri: https://login.microsoftonline.com/xxxxxxxxxxxxxx/oauth2/token
user-info-uri: https://login.microsoftonline.com/xxxxxxxxxxxxxx/openid/userinfo
jwk-set-uri: https://login.microsoftonline.com/xxxxxxxxxxxxxx/discovery/keys
user-name-attribute: name
azure:
activedirectory:
tenant-id: xxxxxxxxxxxxxx
active-directory-groups: Users
The detail error from the log files is
2019-02-08 05:48:28.612 DEBUG 99981 --- [nio-8010-exec-4] o.s.web.client.RestTemplate : Response 401 UNAUTHORIZED
2019-02-08 05:48:28.619 DEBUG 99981 --- [nio-8010-exec-4] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2019-02-08 05:48:28.620 DEBUG 99981 --- [nio-8010-exec-4] .s.o.c.w.OAuth2LoginAuthenticationFilter : Authentication request failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:143) ~[spring-security-oauth2-client-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175) ~[spring-security-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:186) ~[spring-security-oauth2-client-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]

Resources