CORS Несанкционированная ошибка 401 при вызове пружинного остального API - PullRequest
0 голосов
/ 10 июля 2019

У меня нет службы Spring Security в моей службе отдыха, и я сталкиваюсь с несанкционированной проблемой CORS 401 при попытке вызвать ресурсы в состоянии покоя.

Я красный об этом:

https://www.baeldung.com/spring-security-cors-preflight

https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/html5/#cors

У меня есть 2 вызова на отдых:

1) Логин

2) Другие

Функциональность входа в систему основана на Широ, и когда я, например, выполняю вход из Postman, а затем пытаюсь вызвать другой ресурс, он работает.

Моя проблема начинается, когда я начал реализовывать клиентское приложение с реакции, и я пытаюсь вызвать остальное из метода выборки javascript. Я столкнулся с проблемой CORS при первом входе в систему и решил ее, добавив аннотацию @CorsOrigin к своему контроллеру, но после успешного входа в систему второй вызов все еще не выполняется на cors 401.

Если я правильно понимаю, CORS можно решить, добавив фильтр t oWebSecurityConfig, но если мое приложение работает из Postman, то нет необходимости вносить такие изменения в мое приложение на стороне сервера, и я хочу решить его со стороны клиента.

Это оставляет мне возможность передавать JSESSIONID в моих запросах, верно ?! Я до сих пор не понял, как это сделать ... откуда мне взять JSESSIONID? Я попытался прочитать файлы cookie браузера, но не нашел их там ... Я попытался извлечь их из заголовков ответа при первом входе в систему, но ответ пуст!

Пытался решить его с помощью Spring на стороне сервера, но безуспешно:

WebSecurityConfig:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {

//        http
//        .cors();
//        .headers().disable();

//      http
//        .authorizeRequests()
//        .requestMatchers(CorsUtils::isCorsRequest).permitAll()
//        .anyRequest().authenticated()
//        .and().httpBasic()
//        .and().addFilterBefore(new WebSecurityCorsFilter(), ChannelProcessingFilter.class);

        http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);

    }
}

WebSecurityCorsFilter:

public class WebSecurityCorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse res = (HttpServletResponse) response;
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
    res.setHeader("Access-Control-Max-Age", "3600");
    res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control");
    chain.doFilter(request, res);
}

@Override
public void destroy() {
}

}

Или, CorsFilter (используя один из них):

@Component
//@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter{

public CorsFilter () {
    super();
}

@Override
public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
    final HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");

    // without this header jquery.ajax calls returns 401 even after successful login and SSESSIONID being succesfully stored.
    response.setHeader("Access-Control-Allow-Credentials", "true");

    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Authorization, Origin, Content-Type, Version");
    response.setHeader("Access-Control-Expose-Headers", "X-Requested-With, Authorization, Origin, Content-Type");

    final HttpServletRequest request = (HttpServletRequest) req;
    if (!request.getMethod().equals("OPTIONS")) {
        chain.doFilter(req, res);
    } else {
        // do not continue with filter chain for options requests
    }
}

@Override
public void destroy() {

} 

@Override
public void init(FilterConfig filterConfig) throws ServletException {       
}
}

1 Ответ

0 голосов
/ 11 июля 2019

Благодаря этой аналогичной проблеме извлечения: https://github.com/github/fetch/issues/386

Мне удалось наконец.Итак, подведем итог:

1) Нет необходимости вносить изменения в Spring Security Config, за исключением добавления этой аннотации к контроллерам (вы можете добавить ее только один раз в базовый контроллер и все могут наследовать от нее)

@ CrossOrigin (origins = "*", allowHeaders = "*")

2) Со стороны клиента при использовании fetch мне приходилось использовать с оба запросы (логин и второй):

учетные данные: 'include', // 'same-origin'

(обратите внимание, что при использовании cors don 't использовать значение учетных данных 'same-origin')

Нет необходимости устанавливать какие-либо куки вручную, браузер должен их обработать (если вам нужно написать клиент Java, тогда он необходим ... вы можете искатьJava-класс CookiesManagement, и вы найдете такую ​​реализацию)

enter image description here

...