CORS: режим учетных данных - "включить"

100

Да, я знаю, о чем вы думаете - еще один вопрос CORS, но на этот раз я в тупике.

Итак, для начала фактическое сообщение об ошибке:

XMLHttpRequest не может загрузить http: //localhost/Foo.API/token . Значение заголовка «Access-Control-Allow-Origin» в ответе не должно быть подстановочным знаком «*», если режим учетных данных запроса - «включить» . Следовательно, к источнику ' http: // localhost: 5000 ' не разрешен доступ. Режим учетных данных запросов, инициированных XMLHttpRequest, управляется атрибутом withCredentials.

Я не уверен, что подразумевается под режимом учетных данных «включить» ?

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

введите описание изображения здесь

Но когда я обращаюсь к тому же запросу через свое веб-приложение angularjs, эта ошибка меня ставит в тупик. Вот мой запрос / ответ angualrjs. Как вы увидите, ответ есть OK 200, но я все еще получаю ошибку CORS:

Запрос и ответ Fiddler:

Следующее изображение демонстрирует запрос и ответ от веб-интерфейса к API.

Скрипач

Итак, судя по всем остальным сообщениям, которые я читал в Интернете, кажется, что я поступаю правильно, поэтому я не могу понять ошибку. Наконец, вот код, который я использую в angualrjs (фабрика входа в систему):

введите описание изображения здесь

Реализация CORS в API - Справочные цели:

Использованный метод 1:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("*", "*", "*")
        {
            SupportsCredentials = true
        };
        config.EnableCors(cors);
    }
}

Используемый метод 2:

public void Configuration(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();

    ConfigureOAuth(app);

    WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

}

Спасибо заранее!

Ричард Бейли
источник
красивые картинки, какие они? Чтобы ответить на ваш вопрос, если вы включаете аутентификацию, ответ access-control-allow-origin должен быть исходным хостом (страница браузера), это не может быть *- так что сторона сервера выполняет CORS неправильно - о, и почтальон работает, потому что это не запрос на перекрестное происхождение
Jaromanda X
@JaromandaX, спасибо за ответ. Изображения демонстрируют запрос / ответ, а также демонстрируют передаваемые заголовки. Вы задать вопрос, очевидно , утверждает , что он не выполнил это цель ...
Ричард Бейли
Мой комментарий должен быть всем, что вам нужно знать - не нужно было видеть фотографии
Jaromanda X
Так что недавно я решил отказаться от файлов cookie в своем веб-API и использовать токены. Когда я использовал файлы cookie, мой CORS работал без проблем. Поэтому я изо всех сил пытаюсь понять, как CORS не реализован правильно на стороне сервера
Ричард Бейли
1
если вы включаете аутентификацию, access-control-allow-originответ должен быть*
исходным

Ответы:

103

Проблема связана с вашим кодом Angular:

Если withCredentialsустановлено значение true, он пытается отправить учетные данные или файлы cookie вместе с запросом. Поскольку это означает, что другой источник потенциально пытается выполнить аутентифицированные запросы, подстановочный знак («*») не разрешен в качестве заголовка «Access-Control-Allow-Origin».

Чтобы это сработало, вам нужно будет явно ответить источником, который сделал запрос, в заголовке «Access-Control-Allow-Origin».

Я бы порекомендовал явно занести в белый список источники, которым вы хотите разрешить выполнять аутентифицированные запросы, потому что простой ответ с источником из запроса означает, что любой данный веб-сайт может выполнять аутентифицированные вызовы на ваш сервер, если у пользователя есть действующий сеанс.

Я объясняю это в статье, которую написал некоторое время назад.

Таким образом, вы можете либо установить withCredentialsзначение false, либо реализовать белый список происхождения и отвечать на запросы CORS с действительным источником всякий раз, когда задействованы учетные данные.

geekonaut
источник
3
Я работаю над приложением Angular 5 с TypeScript. Мне нужно указать withCredentials как true, иначе я получу исключение Authorization Failed. Как решить эту withCredentials: правда
Ziggler
@Ziggler У меня была такая же ситуация. Вы находите решения?
Павел
@Ziggler Я оштрафован, решение см. Ответ.
Павел
1
Я все еще получаю эту ошибку при использовании WithCredentials = TRUE и Access-Control-Allow-Origin = [' localhost: 4200'] , и я НЕ использую звездочку *, поэтому сообщение об ошибке больше не имеет смысла. СООБЩЕНИЕ ОБ ОШИБКЕ: «Ответ на предпечатный запрос не проходит проверку контроля доступа: значение заголовка 'Access-Control-Allow-Origin' в ответе не должно быть подстановочным знаком *, если режим учетных данных запроса - 'include'. Источник Следовательно, доступ к ' localhost: 4200 ' не разрешен. Режим учетных данных запросов, инициированных XMLHttpRequest, управляется атрибутом withCredentials ".
mruanova 09
@mruanova, вы уверены, что заголовок Access-Control-Allow-Origin правильно установлен в запросе? Похоже, что-то куда-то отправляют с подстановочным знаком
geekonaut
14

Если вы используете промежуточное ПО CORS и хотите отправить withCredentialsлогическое значение true, вы можете настроить CORS следующим образом:

var cors = require('cors');    
app.use(cors({credentials: true, origin: 'http://localhost:5000'}));

`

Анкур Кедиа
источник
11

Настройка CORS для Angular 5 и Spring Security (базовое решение для файлов cookie)

На стороне Angular требуется добавить флаг опции withCredentials: trueдля транспорта Cookie:

constructor(public http: HttpClient) {
}

public get(url: string = ''): Observable<any> {
    return this.http.get(url, { withCredentials: true });
}

На стороне сервера Java требуется добавление CorsConfigurationSourceдля настройки политики CORS:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        // This Origin header you can see that in Network tab
        configuration.setAllowedOrigins(Arrays.asList("http:/url_1", "http:/url_2")); 
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowedHeaders(Arrays.asList("content-type"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...
    }
}

Метод configure(HttpSecurity http)по умолчанию будет использоваться corsConfigurationSourceдляhttp.cors()

Павел
источник
1

Если это помогает, я использовал центрифугу с моим приложением reactjs, и, проверив некоторые комментарии ниже, я посмотрел на файл библиотеки centrifuge.js, который в моей версии имел следующий фрагмент кода:

if ('withCredentials' in xhr) {
 xhr.withCredentials = true;
}

После того, как я удалил эти три строки, приложение заработало нормально, как и ожидалось.

Надеюсь, это поможет!

Густаво Гарсия
источник
1

Если вы используете .NET Core, вам придется использовать .AllowCredentials () при настройке CORS в Startup.CS.

Внутри ConfigureServices

services.AddCors(o => {
    o.AddPolicy("AllowSetOrigins", options =>
    {
        options.WithOrigins("https://localhost:xxxx");
        options.AllowAnyHeader();
        options.AllowAnyMethod();
        options.AllowCredentials();
    });
});

services.AddMvc();

Затем внутри Configure:

app.UseCors("AllowSetOrigins");
app.UseMvc(routes =>
    {
        // Routing code here
    });

Для меня это было просто отсутствие options.AllowCredentials (), которое вызывало указанную вами ошибку. В качестве дополнительного примечания для других, у которых также есть проблемы с CORS, порядок имеет значение, и AddCors () должны быть зарегистрированы перед AddMVC () внутри вашего класса Startup.

Стивен Пфайфер
источник