JWT validation in Spring boot failing

I am trying to implement Okta+Spring Security for a backend Spring boot service. However, whenever I pass a valid access token in the header of any request to the service, a 401 is returned with the error failed to validate the token after the call to the /v1/keys endpoint.
Is this an issue with the application code or some configuration that I am missing?
I have configured a Web application in Okta for this backend spring boot service. Following is my configuration and filter file.

@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
	
	@Override
        protected void configure(HttpSecurity http) throws Exception {
		http
			.csrf().disable()
			.cors().disable()
			.authorizeRequests().anyRequest()
              		.authenticated()
                        .and()
              	        .oauth2ResourceServer().jwt();
		
    }
}
@Component
public class ClaimsAndRemoteJWTValidationFilter implements GlobalFilter {

	@Value("${okta.oauth2.issuer}")
	private String issuerUrl;
	@Value("${okta.oauth2.client-group}")
	private String adminGroup;
	
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		
		ServerHttpRequest request = exchange.getRequest();
		ServerHttpResponse response = exchange.getResponse();
		if(!request.getMethod().toString().equals("GET")){
			String bearerToken = request.getHeaders().getFirst("Authorization").substring(7);
			AccessTokenVerifier jwtVerifier = JwtVerifiers
					.accessTokenVerifierBuilder()
					.setIssuer(issuerUrl)
					.build();
			try {
				Jwt jwt = jwtVerifier.decode(bearerToken);
				List<String> groups = (List<String>) jwt.getClaims().get("groups");
				if(groups.contains(adminGroup))
					return chain.filter(exchange);
				else {
					response.setStatusCode(HttpStatus.FORBIDDEN);
					byte[] bytes = ("User with bearer token not a super admin").getBytes(StandardCharsets.UTF_8);
					DataBuffer buffer = response.bufferFactory().wrap(bytes);
					return response.writeWith(Mono.just(buffer));
				}
			} catch (JwtVerificationException e) {
				e.printStackTrace();
				response.setStatusCode(HttpStatus.UNAUTHORIZED);
				byte[] bytes = ("Failed to parse bearer token, check value").getBytes(StandardCharsets.UTF_8);
		        DataBuffer buffer = response.bufferFactory().wrap(bytes);
		        return response.writeWith(Mono.just(buffer));
			}
		}
		
		return chain.filter(exchange);
		
	}
}

Following is the error thrown in the logs

2022-11-29 12:09:18.555 DEBUG 5784 --- [nio-9876-exec-2] .s.s.w.s.u.m.AndServerWebExchangeMatcher : Trying to match using org.springframework.security.web.server.csrf.CsrfWebFilter$DefaultRequireCsrfProtectionMatcher@7a11e126
2022-11-29 12:09:18.557 DEBUG 5784 --- [nio-9876-exec-2] .s.s.w.s.u.m.AndServerWebExchangeMatcher : Did not match
2022-11-29 12:09:18.561 DEBUG 5784 --- [nio-9876-exec-2] athPatternParserServerWebExchangeMatcher : Request 'GET /migrate/databases' doesn't match 'null /oauth2/authorization/{registrationId}'
2022-11-29 12:09:18.561 DEBUG 5784 --- [nio-9876-exec-2] athPatternParserServerWebExchangeMatcher : Request 'GET /migrate/databases' doesn't match 'null /oauth2/authorization/{registrationId}'
2022-11-29 12:09:18.562 DEBUG 5784 --- [nio-9876-exec-2] athPatternParserServerWebExchangeMatcher : Request 'GET /migrate/databases' doesn't match 'null /login/oauth2/code/{registrationId}'
2022-11-29 12:09:19.728 DEBUG 5784 --- [ctor-http-nio-2] r.netty.http.client.HttpClientConnect    : [44cd2459-1, L:/192.168.1.206:56238 - R:dev-38323351.okta.com/75.2.37.199:443] Handler is being applied: {uri=https://dev-38323351.okta.com/oauth2/default/v1/keys, method=GET}
2022-11-29 12:09:20.325 DEBUG 5784 --- [ctor-http-nio-2] r.n.http.client.HttpClientOperations     : [44cd2459-1, L:/192.168.1.206:56238 - R:dev-38323351.okta.com/75.2.37.199:443] Received response (auto-read:false) : [Date=Tue, 29 Nov 2022 06:39:20 GMT, Content-Type=application/json, Transfer-Encoding=chunked, Connection=keep-alive, Server=nginx, Public-Key-Pins-Report-Only=pin-sha256="r5EfzZxQVvQpKo3AgYRaT7X2bDO/kj3ACwmxfdT2zt8="; pin-sha256="MaqlcUgk2mvY/RFSGeSwBRkI+rZ6/dxe/DuQfBT/vnQ="; pin-sha256="72G5IEvDEWn+EThf3qjR7/bQSWaS2ZSLqolhnO6iyJI="; pin-sha256="rrV6CLCCvqnk89gWibYT0JO6fNQ8cCit7GGoiVTjCOg="; max-age=60; report-uri="https://okta.report-uri.com/r/default/hpkp/reportOnly", x-xss-protection=0, p3p=CP="HONK", content-security-policy=default-src 'self' dev-38323351.okta.com *.oktacdn.com; connect-src 'self' dev-38323351.okta.com dev-38323351-admin.okta.com *.oktacdn.com *.mixpanel.com *.mapbox.com app.pendo.io data.pendo.io pendo-static-5634101834153984.storage.googleapis.com pendo-static-5391521872216064.storage.googleapis.com dev-38323351.kerberos.okta.com *.authenticatorlocalprod.com:8769 http://localhost:8769 http://127.0.0.1:8769 *.authenticatorlocalprod.com:65111 http://localhost:65111 http://127.0.0.1:65111 *.authenticatorlocalprod.com:65121 http://localhost:65121 http://127.0.0.1:65121 *.authenticatorlocalprod.com:65131 http://localhost:65131 http://127.0.0.1:65131 *.authenticatorlocalprod.com:65141 http://localhost:65141 http://127.0.0.1:65141 *.authenticatorlocalprod.com:65151 http://localhost:65151 http://127.0.0.1:65151 https://oinmanager.okta.com data:; script-src 'unsafe-inline' 'unsafe-eval' 'self' dev-38323351.okta.com *.oktacdn.com; style-src 'unsafe-inline' 'self' dev-38323351.okta.com *.oktacdn.com app.pendo.io cdn.pendo.io pendo-static-5634101834153984.storage.googleapis.com pendo-static-5391521872216064.storage.googleapis.com; frame-src 'self' dev-38323351.okta.com dev-38323351-admin.okta.com login.okta.com com-okta-authenticator:; img-src 'self' dev-38323351.okta.com *.oktacdn.com *.tiles.mapbox.com *.mapbox.com app.pendo.io data.pendo.io cdn.pendo.io pendo-static-5634101834153984.storage.googleapis.com pendo-static-5391521872216064.storage.googleapis.com data: blob:; font-src 'self' dev-38323351.okta.com data: *.oktacdn.com fonts.gstatic.com; frame-ancestors 'self', expect-ct=report-uri="https://oktaexpectct.report-uri.com/r/t/ct/reportOnly", max-age=0, cache-control=max-age=4745566, must-revalidate, expires=Mon, 23 Jan 2023 04:52:06 GMT, vary=Origin, x-content-type-options=nosniff, Strict-Transport-Security=max-age=315360000; includeSubDomains, X-Okta-Request-Id=Y4WpGEpAb9MY5gRHgHkk4wAADlk]
2022-11-29 12:09:20.354 DEBUG 5784 --- [ctor-http-nio-2] r.n.http.client.HttpClientOperations     : [44cd2459-1, L:/192.168.1.206:56238 - R:dev-38323351.okta.com/75.2.37.199:443] Received last HTTP packet
2022-11-29 12:09:21.058 DEBUG 5784 --- [ctor-http-nio-2] r.netty.http.client.HttpClientConnect    : [e893c00e-1, L:/192.168.1.206:54559 - R:dev-38323351.okta.com/75.2.37.199:443] Handler is being applied: {uri=https://dev-38323351.okta.com/oauth2/default/v1/keys, method=GET}
2022-11-29 12:09:21.456 DEBUG 5784 --- [ctor-http-nio-2] r.n.http.client.HttpClientOperations     : [e893c00e-1, L:/192.168.1.206:54559 - R:dev-38323351.okta.com/75.2.37.199:443] Received response (auto-read:false) : [Date=Tue, 29 Nov 2022 06:39:21 GMT, Content-Type=application/json, Transfer-Encoding=chunked, Connection=keep-alive, Server=nginx, Public-Key-Pins-Report-Only=pin-sha256="r5EfzZxQVvQpKo3AgYRaT7X2bDO/kj3ACwmxfdT2zt8="; pin-sha256="MaqlcUgk2mvY/RFSGeSwBRkI+rZ6/dxe/DuQfBT/vnQ="; pin-sha256="72G5IEvDEWn+EThf3qjR7/bQSWaS2ZSLqolhnO6iyJI="; pin-sha256="rrV6CLCCvqnk89gWibYT0JO6fNQ8cCit7GGoiVTjCOg="; max-age=60; report-uri="https://okta.report-uri.com/r/default/hpkp/reportOnly", x-xss-protection=0, p3p=CP="HONK", content-security-policy=default-src 'self' dev-38323351.okta.com *.oktacdn.com; connect-src 'self' dev-38323351.okta.com dev-38323351-admin.okta.com *.oktacdn.com *.mixpanel.com *.mapbox.com app.pendo.io data.pendo.io pendo-static-5634101834153984.storage.googleapis.com pendo-static-5391521872216064.storage.googleapis.com dev-38323351.kerberos.okta.com *.authenticatorlocalprod.com:8769 http://localhost:8769 http://127.0.0.1:8769 *.authenticatorlocalprod.com:65111 http://localhost:65111 http://127.0.0.1:65111 *.authenticatorlocalprod.com:65121 http://localhost:65121 http://127.0.0.1:65121 *.authenticatorlocalprod.com:65131 http://localhost:65131 http://127.0.0.1:65131 *.authenticatorlocalprod.com:65141 http://localhost:65141 http://127.0.0.1:65141 *.authenticatorlocalprod.com:65151 http://localhost:65151 http://127.0.0.1:65151 https://oinmanager.okta.com data:; script-src 'unsafe-inline' 'unsafe-eval' 'self' dev-38323351.okta.com *.oktacdn.com; style-src 'unsafe-inline' 'self' dev-38323351.okta.com *.oktacdn.com app.pendo.io cdn.pendo.io pendo-static-5634101834153984.storage.googleapis.com pendo-static-5391521872216064.storage.googleapis.com; frame-src 'self' dev-38323351.okta.com dev-38323351-admin.okta.com login.okta.com com-okta-authenticator:; img-src 'self' dev-38323351.okta.com *.oktacdn.com *.tiles.mapbox.com *.mapbox.com app.pendo.io data.pendo.io cdn.pendo.io pendo-static-5634101834153984.storage.googleapis.com pendo-static-5391521872216064.storage.googleapis.com data: blob:; font-src 'self' dev-38323351.okta.com data: *.oktacdn.com fonts.gstatic.com; frame-ancestors 'self', expect-ct=report-uri="https://oktaexpectct.report-uri.com/r/t/ct/reportOnly", max-age=0, cache-control=max-age=4745566, must-revalidate, expires=Mon, 23 Jan 2023 04:52:06 GMT, vary=Origin, x-content-type-options=nosniff, Strict-Transport-Security=max-age=315360000; includeSubDomains, X-Okta-Request-Id=Y4WpGWInrY4QseIc9UzVvAAAC7E]
2022-11-29 12:09:21.457 DEBUG 5784 --- [ctor-http-nio-2] r.n.http.client.HttpClientOperations     : [e893c00e-1, L:/192.168.1.206:54559 - R:dev-38323351.okta.com/75.2.37.199:443] Received last HTTP packet
2022-11-29 12:09:21.469 DEBUG 5784 --- [ctor-http-nio-2] o.s.s.w.s.a.AuthenticationWebFilter      : Authentication failed: Failed to validate the token

This log is the same for all requests wether or not the access token is valid or if has/has’nt the authorization to access the endpoint being called.

I think I had erroneously configured the authorisation server url while getting the access token, It was configured oauth2/v1/authorize instead of oauth2/default/v1/authorize.

Partly this confusion arose because both these endpoints return Okta tokens.

I was able to figure this out when I inspected the tokens and observed that the tokens with the first endpoints were not returning the claims I had configured.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.