Andrei Budevich
Andrei Budevich

Reputation: 21

An expected CSRF token cannot be found or No static resource oauth2/authorization/l

I have

all project 'org.springframework.boot' version '3.2.3'

  1. spring authorization Oauth 2.0 server http://auth-server:9000
  2. User Interface (React JS application)
  3. Gateway (aka Oauth 2.0 client)
  4. Resource server

Below is the configuration of SecurityConfig Resurce - server

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    public interface Jwt2AuthoritiesConverter extends Converter<Jwt, Collection<? extends GrantedAuthority>> {
    }
    
    @Bean
    Jwt2AuthoritiesConverter authoritiesConverter() {
        return jwt -> {
            @SuppressWarnings("unchecked")
            final Collection<String> roles = (Collection<String>) jwt.getClaims().getOrDefault("roles", List.of());
            return roles.stream().map(role -> new SimpleGrantedAuthority(role)).collect(Collectors.toList());
        };
    }
    
    public interface Jwt2AuthenticationConverter extends Converter<Jwt, AbstractAuthenticationToken> {
    }
    
    @Bean
    Jwt2AuthenticationConverter authenticationConverter(Jwt2AuthoritiesConverter authoritiesConverter) {
        return jwt -> new JwtAuthenticationToken(jwt, authoritiesConverter.convert(jwt));
    }
    
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http,
            Converter<Jwt, AbstractAuthenticationToken> authenticationConverter) throws Exception {
        http.oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer
                .jwt(jwt -> jwt.jwtAuthenticationConverter(authenticationConverter)));
        http.csrf(csrf -> csrf.disable());
        http.securityMatcher("/")
                .authorizeHttpRequests(authorize -> authorize.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        .requestMatchers("/lot-games/api/autogen/**").hasRole("ADMIN")
                        .requestMatchers("/lot-games/api/**").permitAll().anyRequest().authenticated());
        return http.build();
    }

}

I work out the GET methods perfectly well, but as soon as the POST method is used, I get an answer in the browser An expected CSRF token cannot be found, and I understand from the logs that such an answer forms the Gateway, since the logs (even at the springframework: TRACE level) are empty, but on the gateway

[7a7f852d-5] HTTP POST "/lot-games/api/services/v1/games/123", headers={masked} [7a7f852d-5] Completed 403 FORBIDDEN, headers={masked} [7a7f852d-1, L:/127.0.0.1:8072 ! R:/127.0.0.1:51774] Handling completed

I think there's no problem, I'll just add this code to the SecurityConfig gateway - but then everything breaks and I get

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.csrf(Customizer.withDefaults());
        return http.build();
    }
}

or

@Bean
    SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        return http.csrf(CsrfSpec::disable).build();

    } 

but, but everything breaks down and I get an error`

This application has no configured error view, so you are seeing this as a fallback. Mon Mar 11 19:54:33 MSK 2024 [1dd5aeb3-6] There was an unexpected error (type=Not Found, status=404). No static resource oauth2/authorization/lot-games-client-authorization-code. org.springframework.web.reactive.resource.NoResourceFoundException: 404 NOT_FOUND "No static resource oauth2/authorization/lot-games-client-authorization-code." at org.springframework.web.reactive.resource.ResourceWebHandler.lambda$handle$1(ResourceWebHandler.java:431) Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below: Error has been observed at the following site(s): *__checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ LogoutWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ ServerRequestCacheWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ ReactorContextWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ CsrfWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ HttpHeaderWriterWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain] *__checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain] *__checkpoint ⇢ HTTP GET "/oauth2/authorization/lot-games-client-authorization-code" [ExceptionHandlingWebHandler]

Can you help me ?

Upvotes: 2

Views: 443

Answers (1)

izogfif
izogfif

Reputation: 7565

This happens when your SecurityFilterChain has a call to securityMatcher that does not include /oauth2/** path. In your case there is a line

http.securityMatcher("/")

that makes Spring only apply its security configuration (and OAuth one, too) to path / only. Change this line to

http.securityMatcher("/**")

and check if this helps. Alternatively, you can remove securityMatcher("/") call entirely since "/**" is its default value.

Upvotes: 0

Related Questions