使用 ASP.NET Core 5 和 Blazor 的 CORS 策略出错

Iba*_*408 3 asp.net-core blazor

我使用 ASP.NET Core 5 和 WASM Blazor 作为客户端创建了一个 API,但出现以下错误

从源“https://localhost:44351”获取“http://localhost:26173/api/tickets”的访问已被 CORS 策略阻止:“Access-Control-Allow-Origin”标头不存在请求的资源。如果不透明响应满足您的需求,请将请求模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

这是我的 API 中的 Startup 类

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<AppDbContext>(options => 
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddAuthentication(opt => {
        opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,

            ValidIssuer = "https://localhost:44351/",
            ValidAudience = "https://localhost:44351/",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))
        };
    });

    services.AddApiService(Configuration);

    services.AddCors(policy =>
    {
        policy.AddPolicy(name: "ApplicationCors",
                            builder =>
                            {
                                builder
                                  .AllowAnyOrigin()
                                  .AllowAnyMethod()
                                  .AllowAnyHeader();
                            });
    });

    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "HelpDesk.Api", Version = "v1" });
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "HelpDesk.Api v1"));
    }

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

    app.UseCors(builder =>
    {
        builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    });

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}
Run Code Online (Sandbox Code Playgroud)

在我的 WASM 中,这就是我获取列表的方式

protected async override Task OnInitializedAsync()
{
    TicketHeaders = (await TicketService.GetTickets()).ToList();
}
Run Code Online (Sandbox Code Playgroud)

TicketService.cs

public async Task<IEnumerable<TicketHeader>> GetTickets()
{
    return await httpService.Get<TicketHeader[]>("api/tickets");
}
Run Code Online (Sandbox Code Playgroud)

Http服务

public async Task<T> Get<T>(string uri)
{
    var request = new HttpRequestMessage(HttpMethod.Get, uri);
    return await SendRequest<T>(request);
}

private async Task<T> SendRequest<T>(HttpRequestMessage request)
{
    // add jwt auth header if user is logged in and request is to the api url
    var user = await localStorageService.GetItem<ApplicationUserModel>("user");
    var isApiUrl = !request.RequestUri.IsAbsoluteUri;

    if (user != null && isApiUrl)
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", user.Token);

    using var response = await httpClient.SendAsync(request);

    // auto logout on 401 response
    if (response.StatusCode == HttpStatusCode.Unauthorized)
    {
        navigationManager.NavigateTo("login", true);
        return default;
    }

    // throw exception on error response
    if (!response.IsSuccessStatusCode)
    {
        var error = await response.Content.ReadFromJsonAsync<Dictionary<string, string>>();
        throw new Exception(error["message"]);
    }

    return await response.Content.ReadFromJsonAsync<T>();
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

小智 6

您可以尝试以下配置:

 services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder
                    .AllowAnyMethod()
                    .AllowCredentials()
                    .SetIsOriginAllowed((host) => true)
                    .AllowAnyHeader());
        });
Run Code Online (Sandbox Code Playgroud)

并使用它

app.UseCors("CorsPolicy");
Run Code Online (Sandbox Code Playgroud)

将主机设置为 true 意味着它将允许任何浏览器访问该主机。要限制此情况,请将 (host) => true 替换为 (host) => {return host == "my.domain.com";} 以仅允许您的受信任域。

另请参阅:asp net core - 请求的资源上不存在“Access-Control-Allow-Origin”标头