Receiving insufficient_scope when validating access token

Hey everyone,
I’m currently working on a project which will use auth0 for authentication in a NextJS application and then pass the access token to another java spring boot backed API which will validate the access token and then continue with the request, the issue is that i’m receiving "Bearer error=“insufficient_scope”, error_description=“The request requires higher privileges than provided by the access token.” on every request.

Here’s the current code in NextJS:

export default handleAuth({
    async login(req, res) {
      try {
        await handleLogin(req, res, {
          authorizationParams: {
            audience: 'https://my-app.eu.auth0.com/api/v2/',
            scope: 'openid profile email'
          }
        });
      } catch (error) {
        res.status(error.status || 400).end(error.message);
      }
    }
  });

and to make the request to the backend I’m running:

const { accessToken } = await getAccessToken(req, res);

const temp = axios.create({
  baseURL: 'http://localhost:8081',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': `Bearer ${accessToken}`
  }});
  
const res = await temp.get('/api/v1/my-endpoint');

In the Java backend, this is my SecurityConfig:

public class SecurityConfig {
    @Value("${cors.allowed-origins}")
    private String[] allowedOrigins;

    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuer;

    @Value("${auth0.audience}")
    private String audience;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                .requestMatchers("/").permitAll()
                .requestMatchers("/api").authenticated()
                .and().cors()
                .and().oauth2ResourceServer().jwt();
        return http.build();
    }

    @Bean
    JwtDecoder jwtDecoder() {
        NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
                JwtDecoders.fromOidcIssuerLocation(issuer);

        OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(audience);
        OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
        OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);

        jwtDecoder.setJwtValidator(withAudience);
        return jwtDecoder;
    }

    private CorsConfigurationSource corsConfigurationSource() {
        log.info("CORS Allowed Origins: " + Arrays.toString(allowedOrigins));
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers", "Origin", "Content-Type", "Accept", "Authorization"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
        configuration.setAllowedOrigins(Arrays.asList(this.allowedOrigins));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

And this is my AudienceValidator:

class AudienceValidator implements OAuth2TokenValidator<Jwt> {
    private final String audience;

    AudienceValidator(String audience) {
        this.audience = audience;
    }

    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null);

        if (jwt.getAudience().contains(audience)) {
            return OAuth2TokenValidatorResult.success();
        }
        return OAuth2TokenValidatorResult.failure(error);
    }
}

Can you help me figure out what is wrong with this setup?
Cheers

Hey there @leonardotmenezes welcome to the community!

Thanks for the detailed description of the issue you’re running into, very helpful! The first thing that stands out to me is in the following code, you are using your tenants Management API audience as opposed to your own API which you most likely created in your dashboard. You’ll want to use the identifier(audience) of the API you defined in Auth0 as opposed to the management API:

I’m not positive if that will resolve the issue, but it’s a place to start - Keep us posted!

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