Chr*_*ris 6 c# asp.net-core angular asp.net-core-6.0 angular13
我刚刚按照本教程中所述使用 Angular 创建了 ASP.NET Core 应用程序。\n创建 ASP.NET Core 项目时,我选中了启用 Windows 身份验证的选项。只要我添加[AllowAnonymous]到 ASP.NET Core 项目中的控制器,一切就都工作得很好,但一旦我将其替换为[Authorize],来自 Angular 应用程序的请求就不再到达后端的代码。相反,网络服务器会返回400 Bad Request错误。以下是一个包含发生此问题的响应标头的请求:\n
proxy.conf.json经过我自己的一些研究,我发现我可能需要在后端启用 CORS,因为我在开发过程中在 Angular 应用程序中使用代理。以下是 的内容proxy.conf.json:
{\n "/api/*": {\n "target": "https://localhost:7139",\n "secure": false,\n "changeOrigin": true\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n因此,我尝试添加到我的ASP.NET Core 项目UseCors()中。Program.cs这是Program.cs当前的样子:
using Microsoft.AspNetCore.Authentication.Negotiate;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\n\nbuilder.Services.AddCors(setup =>\n{\n setup.AddDefaultPolicy(builder =>\n {\n builder.WithOrigins("http://localhost:4200")\n .AllowAnyHeader()\n .AllowAnyMethod()\n .AllowCredentials();\n });\n});\n\nbuilder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)\n .AddNegotiate();\n\nbuilder.Services.AddAuthorization(options =>\n{\n // By default, all incoming requests will be authorized according to the default policy.\n options.FallbackPolicy = options.DefaultPolicy;\n});\n\nbuilder.Services.AddControllers();\n\nvar app = builder.Build();\n\n// Configure the HTTP request pipeline.\n\napp.UseHttpsRedirection();\n\napp.UseCors();\n\napp.UseAuthentication();\napp.UseAuthorization();\n\napp.MapControllers();\n\napp.Run();\nRun Code Online (Sandbox Code Playgroud)\n不幸的是,这似乎没有任何区别。这就是我的 http GET 调用在前端的实现方式:
\nthis.http.get<string>(`api/test/1`, { responseType: \'text\', withCredentials: true } as Record<string, unknown>).subscribe(value => {\n alert(value);\n }, error => console.error(error));\nRun Code Online (Sandbox Code Playgroud)\n我觉得我错过了一些重要的东西,我需要让 Windows 身份验证在这里工作,但我不知道我到底做错了什么。我什至没有从网络服务器获得任何关于它为什么返回400 Bad Request这里的附加信息,所以我不知道从哪里开始调试这个问题。
Logging更新:我想出了如何通过在我的部分中添加以下配置条目来启用更多 Kestrel 日志记录appsettings.Development.json:
"Default": "Debug",\n"Microsoft.AspNetCore": "Debug",\n"Microsoft.AspNetCore.Server.Kestrel": "Debug",\n"Microsoft.AspNetCore.Server.Kestrel.BadRequests": "Debug",\n"Microsoft.AspNetCore.Server.Kestrel.Connections": "Debug",\n"Microsoft.AspNetCore.Server.Kestrel.Http2": "Debug",\n"Microsoft.AspNetCore.Server.Kestrel.Http3": "Debug"\nRun Code Online (Sandbox Code Playgroud)\n以下是 Kestrel 在处理以错误结束的请求时记录的内容400 Bad Request:
dbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39]\n Connection id "0HMGSHHNJQ68N" accepted.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1]\n Connection id "0HMGSHHNJQ68N" started.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[3]\n Connection 0HMGSHHNJQ68N established using the following protocol: Tls12\ninfo: Microsoft.AspNetCore.Hosting.Diagnostics[1]\n Request starting HTTP/1.1 GET https://localhost:7139/api/test/1 - -\ndbug: Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware[0]\n Wildcard detected, all requests with hosts will be allowed.\ndbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1001]\n 1 candidate(s) found for the request path \'/api/test/1\'\ndbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1005]\n Endpoint \'WebApp.Controllers.TestController.Get (WebApp)\' with route pattern \'api/Test/{id}\' is valid for the request path \'/api/test/1\'\ndbug: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[1]\n Request matched endpoint \'WebApp.Controllers.TestController.Get (WebApp)\'\ndbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[9]\n AuthenticationScheme: Negotiate was not authenticated.\ninfo: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]\n Authorization failed. These requirements were not met:\n DenyAnonymousAuthorizationRequirement: Requires an authenticated user.\ndbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[6]\n Challenged 401 Negotiate.\ninfo: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[12]\n AuthenticationScheme: Negotiate was challenged.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]\n Connection id "0HMGSHHNJQ68N" received FIN.\ninfo: Microsoft.AspNetCore.Hosting.Diagnostics[2]\n Request finished HTTP/1.1 GET https://localhost:7139/api/test/1 - - - 401 0 - 189.6680ms\ndbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]\n Connection id "0HMGSHHNJQ68N" sending FIN because: "The client closed the connection."\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[10]\n Connection id "0HMGSHHNJQ68N" disconnecting.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2]\n Connection id "0HMGSHHNJQ68N" stopped.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39]\n Connection id "0HMGSHHNJQ68O" accepted.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1]\n Connection id "0HMGSHHNJQ68O" started.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[3]\n Connection 0HMGSHHNJQ68O established using the following protocol: Tls12\ninfo: Microsoft.AspNetCore.Hosting.Diagnostics[1]\n Request starting HTTP/1.1 GET https://localhost:7139/api/test/1 - -\ndbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1001]\n 1 candidate(s) found for the request path \'/api/test/1\'\ndbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1005]\n Endpoint \'WebApp.Controllers.TestController.Get (WebApp)\' with route pattern \'api/Test/{id}\' is valid for the request path \'/api/test/1\'\ndbug: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[1]\n Request matched endpoint \'WebApp.Controllers.TestController.Get (WebApp)\'\ninfo: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[1]\n Incomplete Negotiate handshake, sending an additional 401 Negotiate challenge.\ninfo: Microsoft.AspNetCore.Hosting.Diagnostics[2]\n Request finished HTTP/1.1 GET https://localhost:7139/api/test/1 - - - 401 0 - 68.9309ms\ndbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]\n Connection id "0HMGSHHNJQ68O" received FIN.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[10]\n Connection id "0HMGSHHNJQ68O" disconnecting.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]\n Connection id "0HMGSHHNJQ68O" sending FIN because: "The client closed the connection."\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[39]\n Connection id "0HMGSHHNJQ68P" accepted.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[1]\n Connection id "0HMGSHHNJQ68P" started.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2]\n Connection id "0HMGSHHNJQ68O" stopped.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[3]\n Connection 0HMGSHHNJQ68P established using the following protocol: Tls12\ninfo: Microsoft.AspNetCore.Hosting.Diagnostics[1]\n Request starting HTTP/1.1 GET https://localhost:7139/api/test/1 - -\ndbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1001]\n 1 candidate(s) found for the request path \'/api/test/1\'\ndbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1005]\n Endpoint \'WebApp.Controllers.TestController.Get (WebApp)\' with route pattern \'api/Test/{id}\' is valid for the request path \'/api/test/1\'\ndbug: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[1]\n Request matched endpoint \'WebApp.Controllers.TestController.Get (WebApp)\'\ndbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[11]\n Negotiate error code: ClientError.\ndbug: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[10]\n The users authentication request was invalid.\n System.ComponentModel.Win32Exception (0x80090308): Das Token, das der Funktion \xc3\xbcbergeben wurde, ist ung\xc3\xbcltig.\ninfo: Microsoft.AspNetCore.Hosting.Diagnostics[2]\n Request finished HTTP/1.1 GET https://localhost:7139/api/test/1 - - - 400 0 - 40.9717ms\ndbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]\n Connection id "0HMGSHHNJQ68P" received FIN.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[10]\n Connection id "0HMGSHHNJQ68P" disconnecting.\ndbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]\n Connection id "0HMGSHHNJQ68P" sending FIN because: "The client closed the connection."\ndbug: Microsoft.AspNetCore.Server.Kestrel.Connections[2]\n Connection id "0HMGSHHNJQ68P" stopped.\nRun Code Online (Sandbox Code Playgroud)\n第一个连接(0HMGSHHNJQ68N)似乎是我最初在浏览器中输入我的 AD 凭据的登录对话框的地方。当我输入凭据后单击“确定”时,会记录其他连接。遗憾的是,我无法真正弄清楚如何根据这些日志解决问题,但我非常确定 Angular 应用程序未正确提供凭据。
\n我做错了什么和/或如何找出问题的根本原因?
\n在您的 CORS 配置中,您尝试以非常广泛的方式开放 API。不幸的是,在处理包含 AUTHORIZATION 标头的请求时,您不能使用“*”来允许所有主机,而是需要指定主机。此外,您需要调用AllowCredentials以接受带有凭据的请求:
services.AddCors(setup =>
{
setup.AddDefaultPolicy(builder =>
{
builder.WithOrigins("http://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
Run Code Online (Sandbox Code Playgroud)
通常,API 与生产中的 SPA 托管在同一源下,因此在开发以外的环境中可以省略这些设置。另外,您可能想要添加配置设置而不是硬编码http://localhost:4200。