[CORS] [SpringSecurity] Запрос PreFlight не обрабатывается - PullRequest
0 голосов
/ 19 марта 2020

Front end: Реакт 16.12.0 | Back: Spring 2.2.4.RELEASE

В настоящее время я сталкиваюсь с проблемой, связанной с предполетным запросом CORS. Насколько я понимаю, каждый непростой запрос (например, GET с токеном авторизации) будет вызывать предварительный запрос CORS, который сервер должен проверять посредством ответа со всеми разрешенными параметрами, которые должен удовлетворять «реальный» запрос.

Предварительная проверка поступает на стороне сервера как запрос OPTION и должна быть включена в фильтр cors, чтобы его можно было проверить.

Запрос на отправку с внешнего интерфейса:

export function greeting() {
    const access_token = AuthTokenFromStore().oauthData.access_token;
    const obj = {  
        method: 'GET',
        headers: {

        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        'Accept': 'application/json',
            'Authorization': 'Bearer ' + access_token
        }
    };
    return (fetch('http://localhost:8080/api/v1/greeting', obj)
    .then(res => res.json()));
}

Получение сообщения об ошибке:

OPTIONS http://localhost:8080/api/v1/greeting 401
Access to fetch at 'http://localhost:8080/api/v1/greeting' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

конфигурация безопасности пружины:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityServerConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
                .cors() // <-- fetch the corsFilter bean
                .and()
                .csrf().disable()
                .antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/oauth/authorize**", "/login**", "/error**")
                .permitAll()
                .and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }
//...
}

настройка фильтра cors :

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSConfig {
    @Bean
    public CorsFilter corsFilter() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("origin", "x-authorization", "content-type", "accept"));
        configuration.setMaxAge(3600L);
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return new CorsFilter(source);
    }
}

мой журнал:

2020-03-19 17:00:24.993 DEBUG 9452 --- [nio-8080-exec-2] o.a.coyote.http11.Http11InputBuffer      : Received [OPTIONS /api/v1/greeting HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:3000
Sec-Fetch-Dest: empty
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8

]

2020-03-19 17:00:24.994 DEBUG 9452 --- [nio-8080-exec-2] o.a.c.authenticator.AuthenticatorBase    : Security checking request OPTIONS /api/v1/greeting
2020-03-19 17:00:24.994 DEBUG 9452 --- [nio-8080-exec-2] org.apache.catalina.realm.RealmBase      :   No applicable constraints defined
2020-03-19 17:00:24.994 DEBUG 9452 --- [nio-8080-exec-2] o.a.c.authenticator.AuthenticatorBase    : Not subject to any constraint
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/oauth/token']
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/v1/greeting'; against '/oauth/token'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/oauth/token_key']
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/v1/greeting'; against '/oauth/token_key'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/oauth/check_token']
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/v1/greeting'; against '/oauth/check_token'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 1 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 2 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 3 of 10 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 4 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'OPTIONS /api/v1/greeting' doesn't match 'GET /logout'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'OPTIONS /api/v1/greeting' doesn't match 'POST /logout'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'OPTIONS /api/v1/greeting' doesn't match 'PUT /logout'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'OPTIONS /api/v1/greeting' doesn't match 'DELETE /logout'
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2020-03-19 17:00:25.000 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 5 of 10 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
2020-03-19 17:00:25.001 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.o.p.a.BearerTokenExtractor         : Token not found in headers. Trying request parameters.
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] org.apache.tomcat.util.http.Parameters   : Set encoding to UTF-8
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.o.p.a.BearerTokenExtractor         : Token not found in request parameters.  Not an OAuth2 request.
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] p.a.OAuth2AuthenticationProcessingFilter : No token in request, will continue chain.
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 6 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 7 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 9 of 10 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/greeting at position 10 of 10 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/v1/greeting'; against '/api/**'
2020-03-19 17:00:25.006 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /api/v1/greeting; Attributes: [#oauth2.throwOnError(authenticated)]
2020-03-19 17:00:25.010 DEBUG 9452 --- [nio-8080-exec-2] o.s.s.w.a.ExceptionTranslationFilter     : Authentication exception occurred; redirecting to authentication entry point

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

Во время отладки я вижу, как http.cors () правильно получает мой bean-компонент corsFilter, но почему он не отображается в журнале?

Я тестировал множество решений (google reasearcg, учебные пособия, официальные документы по Spring, baeldung, stackoverflow ... et c), никто не работал для меня. Кроме того, фреймворк дает нам способ сделать это правильно, поэтому я хочу избежать добавления фильтра вручную, чтобы обойти запрос OPTIONS (это будет мое последнее средство).

Может ли кто-нибудь помочь мне в этом вопросе? или укажите, что я сделал не так?

Спасибо за помощь!

1 Ответ

0 голосов
/ 20 марта 2020

Выясните проблему, я настроил ResourceServerConfigurerAdapter одновременно с моим WebSecurityConfigurerAdapter. Кажется, что ResourceServerConfigurerAdapter имеет более высокий приоритет, поэтому все мои пользовательские настройки не были приняты во внимание. Единственная цель WebSecurityConfigurerAdapter - предоставить процесс аутентификации для OAuth2. Поэтому я упростил метод настройки до минимума в моей конфигурации безопасности и перенес всю остальную конфигурацию в конфигурацию resourceServer и, в частности, фильтр cors, который был решением для моей первоначальной точки блокировки.

Обсуждается: ResourceServerConfigurerAdapter vs WebSecurityConfigurerAdapter

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...