I am facing an authentication issue in a reactive Spring Boot application using OAuth2 and AWS Cognito. Namely, I configured my app like it's suggested in post here but the problem is that the default login page is failing while authentication attempts or visits.
For redirect-uri
=http://localhost:8080/login/oauth2/code/cognito I am getting For
redirect-uri
=https://fitnesstest.auth.eu-central-1.amazoncognito.com/login/cognito I am receiving
An error was encountered with the requested page.
Funnily enough, I can receive the tokens via postman for the below client-id, client-secret and callback URL but somehow from the spring boot application, it's not possible.
my first approach of application.properties look like:
spring.security.oauth2.client.registration.cognito.client-id=TOP-SECRET-CLIENT-ID
spring.security.oauth2.client.registration.cognito.client-secret=TOP-SECRET
spring.security.oauth2.client.registration.cognito.client-name=fitnesstest
spring.security.oauth2.client.registration.cognito.provider=cognito
spring.security.oauth2.client.registration.cognito.scope=openid
spring.security.oauth2.client.registration.cognito.redirect-uri=http://localhost:8080/login/oauth2/code/cognito
spring.security.oauth2.client.registration.cognito.authorization-grant-type=authorization_code
#provider
spring.security.oauth2.client.provider.cognito.authorization-uri=https://fitnesstest.auth.eu-central-1.amazoncognito.com/oauth2/authorize
spring.security.oauth2.client.provider.cognito.token-uri=https://fitnesstest.auth.eu-central-1.amazoncognito.com/oauth2/token
spring.security.oauth2.client.provider.cognito.user-info-uri=https://fitnesstest.auth.eu-central-1.amazoncognito.com/oauth2/userInfo
spring.security.oauth2.client.provider.cognito.jwk-set-uri=https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_TOP-SECRET-POOL-ID/.well-known/jwks.json
spring.security.oauth2.client.provider.cognito.user-name-attribute=cognito:username
my WebSecurityConfiguration
looks like:
@Configuration
@EnableWebFluxSecurity
@PropertySource("classpath:security.properties")
public class WebSecurityConfiguration {
public static final String ADMIN_LOGIN_URL = "/auth/login";
public static final String USER_LOGIN_URL = "/auth/loginUser";
public static final String LOGOUT_URL = "/auth/signOut";
public static final String SIGNUP_BY_ADMIN_URL = "/auth/signUp";
public static final String SIGNUP_URL = "/auth/registration";
public static final String API_DOCS_URL = "/v2/api-docs";
public static final String NUTRITION_URL = "/nutrition/api/**";
public static final String OAUTH2_URL = "/oauth/**";
public static final String LOGIN_URL = "/login";
public static final String DEFAULT_URL = "/";
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity) {
httpSecurity
.cors()
.and()
.csrf()
.disable()
.httpBasic()
.disable()
.authorizeExchange()
.pathMatchers("/login**", "/oauth2/authorization/**")
.permitAll()
.anyExchange()
.authenticated()
.and()
.oauth2Login();
return httpSecurity.build();
}
}
my pom.xml looks like this:
<?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.6.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fitnessgo</groupId>
<artifactId>api-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api-gateway</name>
<description>api-gateway</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2021.0.0</spring-cloud.version>
<nimbus-jose-jwt>9.15.2</nimbus-jose-jwt>
<aws.sdk.version>1.12.111</aws.sdk.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</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-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</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-actuator</artifactId>
</dependency>
<!--OTHERS-->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus-jose-jwt}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
<!--<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>-->
</dependency>
<!--AWS-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cognitoidp</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-core</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
EDIT: I tried to create a new project with only the oauth2 + spring security configuration and I am still facing the same problem.
I am completely confused why via postman I can receive a token and it's recognizable in jwt.io but from the spring boot application, it's now working as expected. I will be grateful for suggestions on how to reach the desired goal. Cheers.
Turned out that there is a chance to debug Invalid credentials
error for OAuth2 approach. After a suggestion from https://stackoverflow.com/a/62917085/10596295, I debugged the application and realized that there is a problem with the property user-name-attribute
.
My final version of application.yml looks like this:
spring:
security:
oauth2:
client:
registration:
cognito:
client-id: XXX
client-secret: XXX
scope: openid
redirect-uri: http://localhost:8080/login/oauth2/code/cognito
clientName: fitnesstest
provider:
cognito:
issuerUri: https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_XXX