Blazor не может подключиться к ASP.NET Core WebApi (CORS)

У меня есть сервер ASP.NET Core, работающий на локальном IP https://192.168.188.31:44302 с Web API Enpoints. Я могу подключиться к указанному серверу с помощью VS Code REST Client. Теперь я хочу подключиться к веб-API с Blazor WebAssembly, работающим на https://192.168.188.31:5555.

Мой код Blozor:

@page "/login"
@inject HttpClient Http

[ ... some "HTML"-Code ... ]

@code {
    private async Task Authenticate()
    {
        var loginModel = new LoginModel
        {
            Mail = "[email protected]",
            Password = "s3cr3T"
        };
        var requestMessage = new HttpRequestMessage()
        {
            Method = new HttpMethod("POST"),
            RequestUri = ClientB.Classes.Uris.AuthenticateUser(),
            Content =
                JsonContent.Create(loginModel)
        };

        var response = await Http.SendAsync(requestMessage);
        var responseStatusCode = response.StatusCode;

        var responseBody = await response.Content.ReadAsStringAsync();

        Console.WriteLine("responseBody: " + responseBody);
    }

    public async void LoginSubmit(EditContext editContext)
    {
        await Authenticate();
        Console.WriteLine("Debug: Valid Submit");
    }
}

Когда я запускаю LoginSubmit, я получаю следующее сообщение об ошибке в консоли разработчика Chrome и Firefox: login:1 Access to fetch at 'https://192.168.188.31:44302/user/authenticate' from origin 'https://192.168.188.31:5555' 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.

Я новичок в веб-разработке и обнаружил, что вам нужно включить CORS в серверном проекте ASP.NET Core, поэтому я расширил startup.cs с помощью

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<UserDataContext, UserSqliteDataContext>();

services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("https://192.168.188.31:44302",
                "https://192.168.188.31:5555",
                "https://localhost:44302", 
                "https://localhost:5555")
            .AllowAnyHeader()
            .AllowAnyMethod();
        });
});

services.AddControllers();
services.AddApiVersioning(x =>
{
...
});

services.AddAuthentication(x =>
    ...
});
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

services.AddScoped<IViewerService, ViewerService>();
}

public void Configure(IApplicationBuilder app,
    IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    Program.IsDevelopment = env.IsDevelopment();

    app.UseHttpsRedirection();
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();
    app.UseCors(MyAllowSpecificOrigins);

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    Log.Initialize();
}

Но я все еще получаю сообщение об ошибке выше. Я что-то не так делаю с настройкой CORS? Почему он работает должным образом с клиентом VS Code REST и почему я ошибаюсь в вызове в приложении Blazor WASM?


person user3079834    schedule 12.07.2020    source источник
comment
Вы настраиваете CORS на сервере, верно? Непонятен код.   -  person Henk Holterman    schedule 12.07.2020
comment
да, последний фрагмент кода был из файла startup.cs моего серверного проекта ASP.NET Core. Мне тоже нужно что-то настраивать (или больше)?   -  person user3079834    schedule 14.07.2020
comment
Метод Configure () чувствителен к порядку добавления элементов, лучше опубликовать полную версию.   -  person Henk Holterman    schedule 14.07.2020
comment
В вашем with origin у вас есть: 55555 (5x5) в сообщении об ошибке: 5555 (4x5), это просто опечатка?   -  person CobyC    schedule 14.07.2020
comment
@CobyC, у вас действительно хороший глаз, правильный порт - 5555 - я исправил, но все равно ошибка та же.   -  person user3079834    schedule 14.07.2020
comment
Я отредактировал свой вопрос и добавил больше контекста к startup.cs функциям   -  person user3079834    schedule 14.07.2020
comment
Переместите строку UseCors вверх, прямо под UseRouting.   -  person Henk Holterman    schedule 14.07.2020


Ответы (3)


Проблема, вызывающая сообщение об ошибке login:1 Access to fetch at 'https://192.168.188.31:44302/user/authenticate' from origin 'https://192.168.188.31:5555' 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., была вызвана HttpsRedirection.

Чтобы решить эту проблему, либо деактивируйте HttpsRedirection, удалив строку app.UseHttpsRedirection(); в функции Configure, либо добавьте правильные порты для перенаправления в функции ConfigureServices (рекомендуемый способ).

В моем случае я запускаю свой WebAPI на порту 44302, поэтому мое решение выглядит следующим образом (вы должны адаптировать его к своему номеру порта):

if (Program.IsDevelopment)
{
    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
        options.HttpsPort = 44302;
    });
}
else
{
    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
        options.HttpsPort = 443;
    });
}

Также обратите внимание, что достаточно добавить IP-адрес запрашивающего API в CORS следующим образом:

services.AddCors(options =>
{
    options.AddPolicy(name: specificOrigins,
        builder =>
        {
            builder.WithOrigins("https://192.168.188.31:5555",
                "http://192.168.188.31:5444")
            .AllowAnyHeader()
            .AllowAnyMethod();
        });
});
person user3079834    schedule 16.07.2020

Шаг 1. Добавьте следующий код в файл Startup.cs вашего WebAPI, чтобы разрешить CORS с определенным происхождением:

    services.AddCors(options =>
    {
        options.AddDefaultPolicy(builder =>
        builder.WithOrigins("https://localhost:44351")
        .AllowAnyHeader()
        .AllowAnyMethod());
    });

Шаг 2. Теперь измените https: // localhost: 44351 в приведенном выше коде на URL-адрес вашего приложения веб-сборки Blazor. См. Снимок экрана ниже:

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

Шаг 3. Теперь добавьте app.UseCors () в метод Configure вашего WebAPI после app.UseRouting () и перед app.UseRouting (). См. Снимок экрана ниже:

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

Я тоже столкнулся с той же проблемой, и это решило мою проблему. Надеюсь, это сработает и для вас.

Примечание. Никаких изменений в коде веб-сборки Blazor для устранения указанной выше проблемы не требуется.

person Brijesh Kumar Tripathi    schedule 21.03.2021
comment
Сначала я пропустил URL-адрес вашего приложения веб-сборки Blazor. это, конечно, другой номер порта. Как только я ввел адрес вызывающего приложения Blazor, он отлично заработал. - person Dick de Reus; 22.04.2021
comment
@DickdeReus, приятно знать, что это сработало для вас. Спасибо за ваш комментарий. - person Brijesh Kumar Tripathi; 23.04.2021

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

options.AddPolicy(name: MyAllowSpecificOrigins,
    builder =>
    {
        builder.WithOrigins("https://192.168.188.31:44302", 
                   "https://192.168.188.31:55555", 
                   "https://localhost:44302", 
                   "https://localhost:55555")
                 .AllowAnyHeader()
                 .AllowAnyMethod();               
    });
person Henk Holterman    schedule 14.07.2020
comment
Я попробовал, но все равно получаю сообщение об ошибке login:1 Access to fetch at 'https://192.168.188.31:44302/user/authenticate' from origin 'https://192.168.188.31:5555' 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. - person user3079834; 14.07.2020
comment
Да, поместите UseCors () перед UseAuth * () - person Henk Holterman; 14.07.2020
comment
Я поставил его под UseRouting(), все равно без изменений. Что еще я могу сделать? Может я что-то в корне не так делаю? - person user3079834; 14.07.2020
comment
Ик выглядит в основном Хорошо, я не могу заметить ошибку. Может дело в том, что сделай сам HttpRequestMessage. Найдите рабочий образец и сравните заметки. - person Henk Holterman; 15.07.2020
comment
Хорошо, я добился частичного успеха, удаление app.UseHttpsRedirection() из Configure() помогает Chrome. Однако в Firefox у меня все еще есть проблема (даже при установке CORS на AllowAnyOrigin() с сообщением Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://192.168.188.31:44302/user/authenticate. (Reason: CORS request did not succeed).. Что я могу с этим поделать? - person user3079834; 15.07.2020
comment
Обновление: эта проблема связана с неправильно выданным сертификатом (IP-адрес не альтернативного DNS-имени). Теперь все работает нормально. - person user3079834; 15.07.2020
comment
Вы можете опубликовать ответ на этот вопрос. - person Henk Holterman; 16.07.2020