How do I accept an access token in Spring Boot?

I am trying to get an access key then pass the key to my backend spring resource. Currently I can see the frontend getting the request via

let token;
        try {
            token = await input.getAccessTokenSilently({
                audience: '...',
                scope: 'read:transactions'
            });
        } catch (e) {
            token = await input.getAccessTokenWithPopup({
                audience: '...',
                scope: 'read:transactions'
            });
        }
       const response = await fetch(input.endpoint, {
        headers: {
            'Authorization': `Bearer ${input.token}`
        }
       });

This seems to work fine but on the backend I have

@Bean
    public SecurityFilterChain filterChain(
            HttpSecurity http
    ) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
                .oauth2Login(AbstractHttpConfigurer::disable)
                .oauth2ResourceServer(AbstractHttpConfigurer::disable)
                .oauth2ResourceServer((oauth2) -> oauth2
                        .jwt((jwt) -> jwt.decoder(jwtDecoder()))
                )
                .authorizeHttpRequests(
                        (authz) -> authz
                                .requestMatchers(
                                        "/transaction/**"
                                ).authenticated()
                                .requestMatchers(
                                        "/pages/**",
                                        "/api"
                                ).authenticated()
                                .anyRequest().permitAll()
                ).exceptionHandling(handling -> handling
                        .authenticationEntryPoint((request, response, authException) -> {
                            // Redirect to root path for 403 errors
                            response.sendRedirect("/");
                        })
                ).sessionManagement(
                        session -> session
                                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                );
        return http.build();
    }

    @Bean
    JwtDecoder jwtDecoder() {
        NimbusJwtDecoder jwtDecoder = 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 static class AudienceValidator implements OAuth2TokenValidator<Jwt> {
        private final String audience;

        public 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);
        }
    }

This ends up failing and throwing a 401. I can’t seem to check the access token because it doesn’t parse in jwt.io so I was wondering what I might be doing wrong?

It does seem I am getting a opaque token and that I may need to do this…

However this confuses me for 2 reasons.

  1. I may need different permissions for different requests so I can’t really set it at the Provider level. I have previous code that used to work at the token acquisition level but it seems like something changed.

  2. Why do I need to call an access token function if this sort of thing is stored at the Provider level? Why doesn’t it provide it as a variable instead?

This worked

        const audience = '...';
        const scope = 'openid profile read:transactions';
        const authorizationParams = {
            audience,
            scope
        }
        try {
            console.log("Getting token silently");
            token = await input.getAccessTokenSilently({
                authorizationParams
            });
        } catch (e) {
            console.log("Getting token with popup");
            token = await input.getAccessTokenWithPopup({
                authorizationParams
            });
        }