Cors Policy 问题 Blazor WASM、Web API 和 Identity Server 4 和 IIS

Posted

技术标签:

【中文标题】Cors Policy 问题 Blazor WASM、Web API 和 Identity Server 4 和 IIS【英文标题】:Cors Policy problem Blazor WASM, Web API and Identity Server 4 and IIS 【发布时间】:2021-02-05 10:25:41 【问题描述】:

尝试从我的 WASM blazor 应用程序向 Web api 发出 POST 请求时出现 Cors 策略错误。

CORS 策略已阻止从源“https://localhost:8081”获取“http://localhost:8080/DashboardService/TestConnection”的访问权限:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

我在调试模式下没有问题,只有 IIS 发布

Startup.cs (WEB API)

   public class Startup

    #region Fields/Attributes

    private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    private readonly IConfiguration configuration;

    #endregion Fields/Attributes

    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="Startup"/> class.
    /// </summary>
    /// <param name="configuration">The configuration identifier</param>
    public Startup(IConfiguration configuration)
    
        logger.Trace($"GetType().FullName constructed");
        this.configuration = configuration;
    

    #endregion Constructors

    #region Methods

    /// <summary>
    /// This method gets called by the runtime. Use this method to add services to the container.
    /// </summary>
    /// <param name="services">The service collection identifier</param>
    public void ConfigureServices(IServiceCollection services)
    
       

        // Statistics And Monitoring Service
        services.AddSingleton<IDashboardService, DashboardService>();
        services.AddSingleton<IManualLogsService, ManualLogsService>();

        services.AddCors(options =>
        
            options.AddPolicy("CorsPolicy",
              builder =>
              
                  builder
                  .AllowAnyOrigin()
                  .AllowAnyHeader()
                  .AllowAnyMethod();
              );
        );

        services.AddCors(options => options.AddPolicy("CorsPolicy2",
        builder =>
        
            builder.WithOrigins("https://localhost:8081").AllowAnyHeader()
                   .AllowAnyMethod()
                   .AllowCredentials();
        ));

        services.AddSignalR(options =>
        
            options.EnableDetailedErrors = true;
            options.MaximumReceiveMessageSize = long.MaxValue;
            options.ClientTimeoutInterval = TimeSpan.FromSeconds(240);
            options.KeepAliveInterval = TimeSpan.FromSeconds(120);
        )
      

        string identityServerAuthority =  "https://localhost:8082";


        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, opt =>
            
                opt.RequireHttpsMetadata = false;
                opt.Authority = identityServerAuthority;
                opt.Audience = "backend"; 
            );

     
        logger.Trace($"Services configured");
    

    /// <summary>
    /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    /// </summary>
    /// <param name="app">The application builder identifier</param>
    /// <param name="env">The web host environement identifier</param>
    /// <param name="agentsService">The AgentsService identifier</param>
    /// <param name="collectedValueConverter">The CollectedValueConverter identifier</param>
    /// <param name="databaseConnectionService">The DatabaseConnectionService identifier</param>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Dependency injecting only to force instantiation of Singletons")]
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDataBaseServiceApplicationConfig dataBaseServiceApplicationConfig, IAgentsService agentsService, IMachineStructureService machineStructureService, ICollectedValueConverter collectedValueConverter, IDatabaseConnectionService databaseConnectionService)
    
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
        
        else
        
            //app.UseHsts();
        
        //app.UseHttpsRedirection();

        app.UseRouting();

        app.UseCors("CorsPolicy2");
        app.UseAuthentication();

        app.UseAuthorization();

        app.UseStaticFiles();

        app.UseEndpoints(endpoints =>
        
            endpoints.MapControllers(); 
            endpoints.MapHub<BackEndHub>("/DashboardService");
        );
    

    #endregion Methods

我的控制器上有 [Authorize] 属性,如果我删除它们,它就可以工作...

有人可以帮我吗?提前致谢

日痕

【问题讨论】:

如果您发布整个启动课程可能会有所帮助 在您的 wasm 应用中使用HttpClient 时,请尝试在发送前将message.SetBrowserRequestMode(BrowserRequestMode.Cors); 添加到您的HttpRequestMessage 您需要在 IIS 上以 https 方式发布您的 api,并在 IIS 中创建 SSL @HMZ 我尝试了两种解决方案,但仍然出现 cors 策略错误。我不明白的是它与我的控制器上的 [Authorize] 属性有关。它在集成 IS4 之前工作。感谢您的帮助! @Inktkiller 查看之前的评论 【参考方案1】:

我看到的第一个问题是这两行的顺序错误:

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

您应该始终在授权之前进行身份验证。

您还应该知道,您在 IdentityService 客户端定义中有单独的 CORS 设置,但这些(如果我没记错的话)仅在您调用 IdentityServer 端点时应用。

【讨论】:

哦,是的,谢谢,但我在当前版本中更改了它。忘记在此处编辑,但仍然无法正常工作...@Tore Nestenius 更新了我的答案【参考方案2】:

问题已解决: 我去了 Windows 中的事件查看器,能够看到真正的错误,这是一个 SSL 证书问题。我的后端是 http,身份服务器没有这样接受。 我们将后端转为 https 并使用开发证书。 我们面临同样的问题,但这次是存储在 Personal 中而不是 Trusted 中的证书。管理这个的步骤: Windows-> 运行-> mmc.exe --> 证书--> 这台计算机--> 本地--> 将localhost证书复制到trusted中。

感谢大家的帮助。

【讨论】:

以上是关于Cors Policy 问题 Blazor WASM、Web API 和 Identity Server 4 和 IIS的主要内容,如果未能解决你的问题,请参考以下文章

从 Blazor 发出 CORS 请求时如何包含凭据?

Rejected because no crossdomain.xml policy file was found

Rejected because no crossdomain.xml policy file was found

Blazor 无法连接到 ASP.NET Core WebApi (CORS)

Blazor oauth2 被 CORS 阻止

路径不适用于 Blazor 中允许的 IdentityServer CORS 端点,但适用于 Postman