Почему аутентификация Spring Security вызывает ошибку CORS - PullRequest
0 голосов
/ 31 января 2019

У меня есть внутренний сервер, созданный на Java с Spring Boot, Security и Web, и клиент, созданный с Angular.

В настоящее время я пытаюсь сделать простой запрос в localhost:8080/resource.

* 1005.* Контроллер для этого адреса показан ниже:
@RestController
public class IndexController {
    @CrossOrigin
    @RequestMapping("/resource")
    public Map<String, Object> home() {
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("id", UUID.randomUUID().toString());
        model.put("content", "Hello World");

        return model;
    }
}

А угловой клиент (часть, выполняющая запрос) таков:

import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";

@Component({
    selector: "app-root",
    templateUrl: "./app.component.html",
    styleUrls: ["./app.component.css"]
})
export class AppComponent {
    public title = "Security Client";
    public greeting = {};

    constructor(private http: HttpClient) {
        http.get("http://localhost:8080/resource").subscribe(data => this.greeting = data);
    }
}

Проблема с использованием только того, что былопоказано, что я получаю ошибку CORS.

Независимо от того, удаляется ли Spring Security из моего pom.xml или добавляется эта конфигурация:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().antMatchers("/resource").permitAll();
    }
}

Решает проблему.

Что яхочу знать, почему я получаю ошибку CORS вместо 401 Unauthorized при доступе к адресу, который требует аутентификации пользователя.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

То, что я хочу знать, это , почему я получаю ошибку CORS вместо 401 Несанкционированный при доступе к адресу, который требует аутентификации пользователя.

Вы получаете этоошибка, потому что перед вашим фактическим запросом (POST, GET ...) браузер выполняет предполетный запрос ( OPTIONS ), чтобы проверить, действительно ли вызываемый сервер способен обрабатывать запросы CORS.

Во время этого запроса Access-Control-Request-Method и Access-Control-Request-Header проверяются, и некоторая другая информация добавляется в заголовок.

Тогда вы получаете ошибку CORS, потому что ваш фактический запрос даже не выполнен если проверка CORS завершилась неудачно по запросу OPTIONS.

Вы можете проверить блок-схему того, как работает проверка CORS здесь

ИнтересноДело в том, что вы получите статус ошибки HTTP, например 401, во время предполетного запроса, когда сервер не авторизован для ответа на запрос OPTIONS.

0 голосов
/ 31 января 2019

Согласно документации по весенней загрузке:

В целях безопасности браузеры запрещают вызовы AJAX ресурсам за пределами текущего источника.Например, вы можете иметь свой банковский счет на одной вкладке и evil.com на другой.Скрипты с сайта evil.com не должны отправлять запросы AJAX в API вашего банка с вашими учетными данными - например, снимать деньги со своего счета!

Обмен ресурсами между источниками (CORS) - это спецификация W3C, реализованная большинствомбраузеры, позволяющие указать, какие типы междоменных запросов разрешены, вместо использования менее безопасных и менее мощных обходных путей на основе IFRAME или JSONP.

Вы получаете эту ошибку, потому что вам нужно добавитьфильтр в вашей конфигурации безопасности.В вашей конфигурации добавьте:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors()
    .and()
    .authorizeRequests().antMatchers("/resource").permitAll();
}

В том же файле вы должны добавить:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", 
    "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", 
    "x-auth-token"));
    configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
    UrlBasedCorsConfigurationSource source = new 
    UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);

    return source;
}

Это прекрасно работает для меня.

...