![](/img/trans.png)
[英]How to forward/pass windows authentication from client to another REST API in an ASP.NET Core app with Angular?
[英]How to properly implement Windows Authentication in an ASP.NET Core app with Angular
我剛剛創建了一個 ASP.NET Core 應用程序,其中包含 Angular,如本教程中所述。 在創建 ASP.NET 核心項目時,我勾選了啟用 Windows 身份驗證的選項。 只要我在 ASP.NET 核心項目中將[AllowAnonymous]
添加到我的控制器,一切都已經正常工作,但是一旦我將其替換為[Authorize]
,來自我的 Angular 應用程序的請求就不再到達我在后端的代碼。 相反,網絡服務器返回400 Bad Request
錯誤。 這是一個包含出現此問題的響應標頭的請求:
在我自己做了一些研究之后,我發現我可能需要在后端啟用 CORS,因為我在開發期間通過proxy.conf.json
在 Angular 應用程序中使用代理。 這是proxy.conf.json
的內容:
{
"/api/*": {
"target": "https://localhost:7139",
"secure": false,
"changeOrigin": true
}
}
因此,我嘗試在 ASP.NET Core 項目的Program.cs
中添加UseCors()
。 這是Program.cs
當前的樣子:
using Microsoft.AspNetCore.Authentication.Negotiate;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddCors(setup =>
{
setup.AddDefaultPolicy(builder =>
{
builder.WithOrigins("http://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
不幸的是,這似乎沒有任何區別。 這就是我的 http GET 調用在前端的實現方式:
this.http.get<string>(`api/test/1`, { responseType: 'text', withCredentials: true } as Record<string, unknown>).subscribe(value => {
alert(value);
}, error => console.error(error));
我覺得我缺少一些重要的東西,我需要讓 Windows 身份驗證在這里工作,但我不知道我到底做錯了什么。 我什至沒有從網絡服務器那里得到任何關於它為什么在這里返回400 Bad Request
的額外信息,所以我不知道從哪里開始調試這個問題。
更新:我想出了如何通過在我的appsettings.Development.json
的Logging
部分添加以下配置條目來啟用更多 Kestrel-Logging:
"Default": "Debug",
"Microsoft.AspNetCore": "Debug",
"Microsoft.AspNetCore.Server.Kestrel": "Debug",
"Microsoft.AspNetCore.Server.Kestrel.BadRequests": "Debug",
"Microsoft.AspNetCore.Server.Kestrel.Connections": "Debug",
"Microsoft.AspNetCore.Server.Kestrel.Http2": "Debug",
"Microsoft.AspNetCore.Server.Kestrel.Http3": "Debug"
以下是 Kestrel 在處理以400 Bad Request
錯誤結尾的請求時記錄的內容:
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39]
Connection id "0HMGSHHNJQ68N" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1]
Connection id "0HMGSHHNJQ68N" started.
dbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[3]
Connection 0HMGSHHNJQ68N established using the following protocol: Tls12
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:7139/api/test/1 - -
dbug: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[0]
Wildcard detected, all requests with hosts will be allowed.
dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1001]
1 candidate(s) found for the request path '/api/test/1'
dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1005]
Endpoint 'WebApp.Controllers.TestController.Get (WebApp)' with route pattern 'api/Test/{id}' is valid for the request path '/api/test/1'
dbug: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[1]
Request matched endpoint 'WebApp.Controllers.TestController.Get (WebApp)'
dbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[9]
AuthenticationScheme: Negotiate was not authenticated.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed. These requirements were not met:
DenyAnonymousAuthorizationRequirement: Requires an authenticated user.
dbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[6]
Challenged 401 Negotiate.
info: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[12]
AuthenticationScheme: Negotiate was challenged.
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]
Connection id "0HMGSHHNJQ68N" received FIN.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET https://localhost:7139/api/test/1 - - - 401 0 - 189.6680ms
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]
Connection id "0HMGSHHNJQ68N" sending FIN because: "The client closed the connection."
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[10]
Connection id "0HMGSHHNJQ68N" disconnecting.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2]
Connection id "0HMGSHHNJQ68N" stopped.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39]
Connection id "0HMGSHHNJQ68O" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1]
Connection id "0HMGSHHNJQ68O" started.
dbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[3]
Connection 0HMGSHHNJQ68O established using the following protocol: Tls12
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:7139/api/test/1 - -
dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1001]
1 candidate(s) found for the request path '/api/test/1'
dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1005]
Endpoint 'WebApp.Controllers.TestController.Get (WebApp)' with route pattern 'api/Test/{id}' is valid for the request path '/api/test/1'
dbug: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[1]
Request matched endpoint 'WebApp.Controllers.TestController.Get (WebApp)'
info: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[1]
Incomplete Negotiate handshake, sending an additional 401 Negotiate challenge.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET https://localhost:7139/api/test/1 - - - 401 0 - 68.9309ms
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]
Connection id "0HMGSHHNJQ68O" received FIN.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[10]
Connection id "0HMGSHHNJQ68O" disconnecting.
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]
Connection id "0HMGSHHNJQ68O" sending FIN because: "The client closed the connection."
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39]
Connection id "0HMGSHHNJQ68P" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1]
Connection id "0HMGSHHNJQ68P" started.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2]
Connection id "0HMGSHHNJQ68O" stopped.
dbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[3]
Connection 0HMGSHHNJQ68P established using the following protocol: Tls12
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET https://localhost:7139/api/test/1 - -
dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1001]
1 candidate(s) found for the request path '/api/test/1'
dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1005]
Endpoint 'WebApp.Controllers.TestController.Get (WebApp)' with route pattern 'api/Test/{id}' is valid for the request path '/api/test/1'
dbug: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[1]
Request matched endpoint 'WebApp.Controllers.TestController.Get (WebApp)'
dbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[11]
Negotiate error code: ClientError.
dbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[10]
The users authentication request was invalid.
System.ComponentModel.Win32Exception (0x80090308): Das Token, das der Funktion übergeben wurde, ist ungültig.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET https://localhost:7139/api/test/1 - - - 400 0 - 40.9717ms
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]
Connection id "0HMGSHHNJQ68P" received FIN.
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[10]
Connection id "0HMGSHHNJQ68P" disconnecting.
dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]
Connection id "0HMGSHHNJQ68P" sending FIN because: "The client closed the connection."
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2]
Connection id "0HMGSHHNJQ68P" stopped.
第一個連接 (0HMGSHHNJQ68N) 似乎是我最初在瀏覽器中輸入我的 AD 憑據的登錄對話框。 當我輸入我的憑據后點擊確定時,其他連接就會被記錄下來。 遺憾的是,我真的無法根據這些日志找出解決問題的方法,但我很確定 Angular 應用程序未正確提供憑據。
我做錯了什么和/或我怎樣才能找出問題的根本原因?
在您的 CORS 配置中,您嘗試以非常廣泛的方式打開 API。 不幸的是,在處理包含 AUTHORIZATION header 的請求時,您不能使用“*”來允許所有主機,但您需要指定主機。 此外,您需要調用AllowCredentials
來接受帶有憑據的請求:
services.AddCors(setup =>
{
setup.AddDefaultPolicy(builder =>
{
builder.WithOrigins("http://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
通常,API 與生產中的 SPA 同源托管,因此在 dev 以外的環境中可以省略這些設置。 此外,您可能希望添加配置設置而不是硬編碼http://localhost:4200
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.