簡體   English   中英

CORS 策略不想與 SignalR 和 ASP.NET 核心一起使用

[英]CORS policy don't want to work with SignalR and ASP.NET core

我的 ASP.NET 核心 API 和 Angular 客戶端有問題。 我想實現 SignalR 以在 API 和 Angular 之間建立連接。 cors 策略已經在我們的客戶端和 API 上激活,因為我們已經可以使用我們的客戶端從 API 檢索數據。 但現在的問題是,當我嘗試使用 SignalR 時,收到 CORS 策略錯誤:

從源“ http://localhost:4200 ”訪問“ http://localhost:50501/CoordinatorHub/negotiate ”的 XMLHttpRequest 已被 CORS 策略阻止:對預檢請求的響應未通過訪問控制檢查:無“訪問” -Control-Allow-Origin' 標頭存在於請求的資源上。

但是我們 API 的 Startup.cs 中已經有 cors 策略,就像這樣:

在 ConfigureServices 方法中:

services.AddCors(options =>
{
    options.AddPolicy("AllowSpecificOrigin",
        builder => 
        builder.WithOrigins("http://localhost:4200/")
            .AllowCredentials()
            //.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .SetIsOriginAllowedToAllowWildcardSubdomains());
});

在 Configure 方法中:

app.UseCors("AllowSpecificOrigin");

在我們的客戶端中,我們只想嘗試在 API 和客戶端之間建立連接,就像這樣:

this.hubConnection.start({withCredentials: false}).then(() => 
     this.hubConnection.invoke('send', 'Hello'));

請注意,這可以應用於 .net core 3.1

正如它在 microsoft docs 上所說,它似乎不起作用docs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Preceding code ommitted.
    app.UseRouting();

    app.UseCors();

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

    // Following code ommited.
}

警告

對於端點路由,必須將 CORS 中間件配置為在對 UseRouting 和 UseEndpoints 的調用之間執行。 不正確的配置將導致中間件停止正常運行。

但是,如果您首先移動 UseCors(),您的應用程序將按預期工作,因此工作代碼將是

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
                options.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//place your useCors here 
    app.UseCors();
    app.UseRouting();


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

    // Following code ommited.
}

接受的答案對我不起作用,所以我決定把對我有用的東西放在這里。 萬一有人偶然發現同樣的問題。

在 Angular 9 上使用 signalR 時,我在本地測試中遇到了同樣的問題。

我通過將我的 Asp NET Core (3.1) 應用 URL 從 https 切換到 http 來解決它。 如果您使用的是 Visual Studio,

  1. 只需右鍵單擊項目屬性-> 調試。
  2. 取消選中啟用 SSL

Asp網絡核心項目

也不要忘記在 angular App 中更改 URL 上的端口。 所以基本上角度應用程序中的 URL 將是這樣的

this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:50782/hub").build();

而配置方法中的相關代碼是這樣的

app.UseHttpsRedirection();
app.UseStaticFiles();

   
app.UseRouting();
app.UseCors("_myAllowSpecificOrigins");

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapHub<ChatHub>("/hub");
});

在你的 configureServices 方法中,我遵循了

    services.AddRazorPages();

    services.AddCors(options =>
        {
            options.AddPolicy("_myAllowSpecificOrigins",
                builder =>
                {
                    builder.WithOrigins("https://localhost:4200")
                           .AllowAnyHeader()
                           .AllowAnyMethod()
                           .SetIsOriginAllowed((x) => true)
                           .AllowCredentials();
                });
        });
    
   services.AddSignalR();

希望這可以幫助 !

更新

如果你只是玩弄你的本地計算機上的樣品,你也可以嘗試運行安全模式鉻提到這里

在我的 Mac 上,我只是簡單地從終端運行命令

open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security

有了這個,您應該能夠在沒有 CORS 打擾的情況下運行您的示例

我根據這個鏈接解決了我的問題

將此塊代碼添加到服務

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

並在配置應用程序中添加此塊代碼

app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
        {
            routes.MapHub<General>("/hubs/general");
        });

在你的啟動配置類中嘗試這樣的事情:

app.Map("/CoordinatorHub/negotiate", map =>
{
    map.UseCors(CorsOptions.AllowAll);
    var hubConfiguration = new HubConfiguration 
    {
        // You can enable JSONP by uncommenting line below.
    // EnableDetailedErrors = true,
        // EnableJSONP = true

    };
    map.RunSignalR(hubConfiguration);
});

我有一個類似的問題,我掙扎了 6 個小時。

原來我的起源結尾有一個斜線。

所以而不是:

.WithOrigins("https://aaa.azurewebsites.net/")

用:

.WithOrigins("https://aaa.azurewebsites.net")

為什么最后的斜線不只是被剝離超出了我的理解。

最近我在 .Net Core 3.1 中遇到了同樣的問題,當我在 Azure App 服務中部署時問題開始,最后能夠使用以下代碼解決問題。

我在 Startup.cs 文件的 ConfigureServices 函數中使用以下代碼

services.AddCors(options =>
        {
            var corsUrls = Configuration.GetSection("App:CorsOrigins").Value.ToString()
                      .Split(",", StringSplitOptions.RemoveEmptyEntries)
                             .Select(o => o.Trim('/'))
                             .ToArray();
            options.AddPolicy("CorsPolicy",
            builder =>
            {
                builder.WithOrigins(corsUrls)
                       .AllowAnyHeader()
                       .AllowAnyMethod()
                       .AllowCredentials();
            });
        });

然后在Configure函數中添加如下代碼

app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
  {
    endpoints.MapControllers();
    endpoints.MapHub<WebhookHub>("/Webhook");
  });

不要忘記在 appsetting.json 文件中添加以下部分

"App": {
"CorsOrigins": "https://myservice.com" }

在 .Net Core 3.1+ 和 Angular 8+ 版本和 android 19+ api 級別的 signalR 上進行測試,並且也適用於 iOS 設備

.Net核心代碼

public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy", builder => builder.WithOrigins("http://localhost:4200")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials()
                );
            });


            services.AddRazorPages();
            services.AddAccessTokenService();
            services.AddSignalR()
                 .AddHubOptions<ChatHub>(options => options.EnableDetailedErrors = true)
                 .AddJsonProtocol(options =>
                 {
                     options.PayloadSerializerOptions.PropertyNamingPolicy = null;
                  }); ;
            services.AddSingleton<IUserIdProvider, NameUserIdProvider>();

        }



public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseCors("CorsPolicy");

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

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapRazorPages();
                endpoints.MapHub<ChatHub>("/chathub");
            });

        }

-- Angular 代碼替換了 url 和令牌(可選部分),並且它正在工作--

public startConnection = () => {
  this.hubConnection = new signalR.HubConnectionBuilder()
                          .withUrl(this.url,{ accessTokenFactory: () => this.token},)
                          .build();

  this.hubConnection
    .start()
    .then(() => console.log('Connection started'))
    .catch(err => console.log('Error while starting connection: ' + err))
}

   ngOnInit(): void {
      this.startConnection();

  }

在做了大量研究之后,我還想分享我所面臨的問題以及我是如何解決的。

我的情況是; 我在Azure App Services上部署了我的.Net Core應用以及Azure SignalR配置。 當我在本地機器上運行前端和后端時,一切正常。 但是當我在 azure 服務上部署我的應用程序時,由於這個../Hub/negotiate和 cors 問題,我無法連接。

我是如何修復的; 首先確保你已經在你的 api 中啟用了 cors 設置,正如這里的朋友指出的那樣。 我在此鏈接中從 Microsoft 文檔中獲取了我的示例 signalR 應用程序。 最后我意識到在項目示例中@aspnet/signalr@1.0.0包已過時並移至@microsoft/signalr 在我的研究中,我在某些地方看到withCredentials應該設置為 false,因為默認情況下該值為 true 並強制連接使用 SSL。 我的客戶端應用程序正在使用 http 本地運行並嘗試連接 https 連接。 有關更多信息,請參閱此鏈接 在舊的 signalR npm 包中,這個值沒有設置,所以我一切換到新的, withCredentials屬性被激活,我把它設置為 false。 一切都開始正常工作。

我最后的集線器建造者是這樣的;

var connection = new signalR.HubConnectionBuilder()
            .withUrl('https://**chat.azurewebsites.net/chat', {
                accessTokenFactory: () => 'InR5cCI6IkpXVCJ9.eyJpZCI6I',
                withCredentials: false
            }).build();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM