簡體   English   中英

使用 Windows 身份驗證的 Asp.net 核心 Web api - Cors 請求未經授權

[英]Asp.net core web api using windows authentication - Cors request unauthorised

在我的 asp.net core web api 中,我已經按照MS 文檔中的文章配置了 Cors。 Web api 應用程序正在使用 Windows 身份驗證(未啟用匿名身份驗證)。 startup.cs創建了Cor的策略並添加了中間件,如下所示

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

    services.AddMvc().AddJsonOptions(options => {
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{         
    //Enable CORS policy 
    app.UseCors("CorsPolicy");
    app.UseMvc();
}

還應用了每個控制器級別的策略

[EnableCors("CorsPolicy"), Route("api/[controller]")]
public class LocationController : BaseController<Location>
{
  //code
}

選項請求變得未經授權。 請求和響應看起來像

在此處輸入圖片說明

我見過類似的問題並嘗試了幾乎所有解決方案,但選項請求仍然失敗。

您可能想閱讀此線程: https : //github.com/aspnet/CORS/issues/60 您可以混合使用匿名和 NTLM,以便不會拒絕您的 CORS 預檢(因為它們不包含 Windows 憑據)。 IIS 在它到達中間件之前處理 NTLM 身份驗證,所以這可能是 IIS 的事情。 您可能需要允許匿名 COR 預檢。

1) 在launchSettings.json 文件(開發設置文件)中將Allow Windows 和anonymous Authentication 標志設置為true。

匿名身份驗證:需要允許飛行前選項請求。

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iis": 
      ...
}

2) 在配置服務方法中添加 Cors 策略。

public void ConfigureServices(IServiceCollection services)
{
         
        ...
          services.AddCors(options =>
              {
                  options.AddPolicy("MyCustomCorsPolicyName",
                              builder => builder.WithOrigins("http://YourDomainName/")
                                      .AllowAnyMethod()
                                      .AllowAnyHeader()
                                      .AllowCredentials()
                              );
              });
          services.AddAuthentication(IISDefaults.AuthenticationScheme);
          services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);      
}
   

3:將 CORS 中間件添加到您的 Web 應用程序管道以允許跨域請求。

public void Configure(IApplicationBuilder app)
{
   ....
   app.UseCors("MyCustomCorsPolicyName");
   app.UseMvc();
}

4)在控制器頂部添加授權屬性以強制,客戶端發送憑據

[Authorize]
public class MyAPIController : ControllerBase
{
...
}

5) 在 JQuery 或您使用的任何客戶端中,將 withCredentials 屬性標志設置為 true

$.ajax({
                type: "POST",
                datatype: "json",  
                url: "YourApiUrl",              
                xhrFields: {
                    withCredentials: true
                }

這在我使用 .net core 2.2、帶有 Windows 身份驗證的 IIS Express 的開發環境中對我有用。

使用 IIS CORS 模塊很好地解決了這個問題。 以下網址供參考。

使用 Windows 身份驗證 雖然這絕不是 CORS 模塊解決的唯一方案,但它非常重要,值得一提。 以前,如果您嘗試向使用 Windows 身份驗證的應用程序發出跨域請求,您的預檢請求將失敗,因為瀏覽器未隨預檢請求發送憑據。 如果不在您的應用程序中啟用匿名身份驗證,則無法解決此問題。 由於 CORS 模塊在身份驗證之前啟動,因此可以在不影響應用程序安全模型的情況下處理飛行前請求。 下面是您的 web.config 可能是什么樣子的示例。

https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module

示例代碼:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- To customize the asp.net core module uncomment and edit the following section. 
         For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
         <system.web>
        <authentication mode="Windows"/>
    </system.web>
  <system.webServer>
  <cors enabled="true" failUnlistedOrigins="true">
            <add origin="http://localhost:60096" allowCredentials="true" >
            <allowHeaders allowAllRequestedHeaders="true">
                    <add header="Header1" />
                </allowHeaders>
            </add>
        </cors>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\Project.Api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>

這與啟用 CORS非常相似, 在 POST JSON並為我提供解決方案時,預檢響應具有無效的 HTTP 狀態代碼 404 (我在 POST 請求上出現 401 錯誤)。 此外,不應同時配置 NTLM 和協商( 協商 V/s NTLM )。

看起來您想要傳遞憑證或與請求一起傳遞。

請檢查此鏈接以添加憑據/允許用戶憑據。

允許跨域憑據時要小心。 另一個域中的網站可以在用戶不知情的情況下代表用戶將登錄用戶的憑據發送到應用程序。 CORS 規范還指出,如果存在 Access-Control-Allow-Credentials 標頭,則將來源設置為“*”(所有來源)是無效的。

經過幾個小時的研究,這是一個完整的解決方案(前端到后端):

我的問題:當我在我的 Web API 上啟用 Windows 身份驗證時,我無法從我的 React 應用程序獲取調用到我的 .NET Core 3.1 Web API,CORS 嚇壞了。 使用匿名身份驗證它有效,但在啟用 Windows 身份驗證時無效。

1.launchSettings.json

這將僅用於您的開發環境,請確保在您的生產服務器上的 IIS 中也啟用了 Windows 身份驗證。

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:58747",
      "sslPort": 0
    }
  },
 {... more settings if any}
}

2.Startup.cs:

此處啟用 CORS 策略。 方法的順序在這里很重要。 此外,您不需要在 web.config 中設置它們

public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy", //give it the name you want
                           builder =>
                           {
                               builder.WithOrigins( "http://localhost:3000", //dev site
                                                    "production web site"
                                                   .AllowAnyHeader()
                                                   .AllowAnyMethod()
                                                   .AllowCredentials();
                           });
        });

        //database services here

        services.AddControllers();
    }

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

        app.UseRouting();

        // global policy same name as in the ConfigureServices()
        app.UseCors("CorsPolicy");

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

3.控制器:

using Microsoft.AspNetCore.Cors;
... your other usings

namespace ProjectTest.Controllers
{
    [ApiController]
    [EnableCors("CorsPolicy")] //THIS HERE needs to be the same name as set in your startup.cs
    [Route("[controller]")]
    public class FooController:Controller
    {
        [HttpGet("getTest")]
        public JsonResult GetTest()
        {
            return Json("bar");
        }
    }
}

4.React 組件獲取調用示例:

“憑證:'包含'”是秘密

    await fetch('http://localhost:3000/Foo/getTest', {
        method: 'GET',
        credentials: 'include'
    }).then(resp => resp.json());

只是注意 CORS 中間件在 IIS 中不起作用,請在此處查看此線程

  1. 在 IIS 中安裝CORS 模塊
  2. 轉換您的 web.config(順便說一句,我使用的是 .net core 3.1)
  3. 在應用的根目錄添加web.release.config
  4. 遵循此 XML 代碼
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

  <system.web xdt:Transform="Insert">
    <authentication mode="Windows"/>
  </system.web>

  <system.webServer xdt:Transform="Insert">
    <cors enabled="true" failUnlistedOrigins="true" >
      <add origin="your origin" allowCredentials="true" >
        <allowHeaders allowAllRequestedHeaders="true">
          <add header="your header" />
        </allowHeaders>
      </add>
    </cors>
  </system.webServer>

</configuration>
  1. 在 IIS 中部署您的應用程序

暫無
暫無

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

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