Reputation: 1
I have set up a Spring Book application, and have just started to add authentication. I am using JWT tokens (from Amazon Cognito) for validation.
I want certain endpoints (eg requests from the login page) to not require a valid JWT token. When I have a valid JWT token the authentication is successful so I know that token validation is working. However, for certain endpoints (eg "initiate-sign-in-auth") a token shouldn't be required but it still is. When a request is made to this endpoint I receive a 401 error with the error:
May 3 13:47:37 ip-172-31-30-116 web[1423242]: 2024-05-03T13:47:37.061Z DEBUG 1423242 --- [nio-5000-exec-5] o.s.s.oauth2.jwt.JwtTimestampValidator : Jwt expired at 2024-05-03T12:35:46Z
May 3 13:47:37 ip-172-31-30-116 web[1423242]: 2024-05-03T13:47:37.062Z DEBUG 1423242 --- [nio-5000-exec-5] o.s.s.o.s.r.a.JwtAuthenticationProvider : Failed to authenticate since the JWT was invalid
While this is correctly invalidating the token, it shouldn't be checking the token for this endpoint due to the use of .permitAll() in the SecurityConfig.
I have read online that the Authentication comes before the Authorisation, and therefore the JWT token is checked before the authorizeHttpRequests is checked. This may be true, but I don't know how to add .permitAll() to the oauth2ResourceServer.
I have added the following SecurityConfig:
@EnableWebSecurity
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
System.out.println("entering the SecurityChainFilter");
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/initiate-sign-in-auth").permitAll()
.anyRequest().permitAll()
)
.csrf(AbstractHttpConfigurer::disable)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
}
Here are the security dependencies I have added to my pom.xml file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<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>
Here is the endpoint I am trying to call:
@PostMapping("/initiate-sign-in-auth")
public InitiateAuthRequestResponse initiateSignInAuth(@RequestBody InitiateAuthRequestRequest request) throws JsonProcessingException, StripeException {
System.out.printf("Starting initiateSignInAuth request: %s%n", om.writeValueAsString(request));
InitiateAuthRequestResponse response = initiateSignInAuthExecutor.execute(request);
System.out.printf("InitiateSignInAuthResponse: %s%n", om.writeValueAsString(response));
return response;
}
I have been stuck on this for a few days so any help would be greatly appreciated! Thank you
I have tried removing the oauth2ResourceServer, when I do the .permitAll() works as expected. So I know the issue is related to the oauth2ResourceServer validating the JWT token. I have also tried disabling CSRF but the issue still remains.
I have also tried adding .permitAll() to .anyRequest() incase there was an issue with the endpoint configuration but this also doesn't resolve the issue. So I know it isn't because of the endpoint string I am using.
Upvotes: 0
Views: 781
Reputation: 12825
A resource server filter-chain will always reject an invalid token (wrong issuer, expired, bad signature, wrong audience, or whatever the token validator / introspector is configured to check). The exception is thrown before access control is evaluated, so just don't send a token to endpoints configured with permitAll()
.
If you really want to accept junk tokens to certain endpoints, exclude it from the resource server security filter-chain. You may create another filter-chain with higher precedence and a security matcher intercepting just this unsecured endpoints.
Upvotes: 0