Windows 身份验证适用于 IIS,但不适用于 Kestrel / Microsoft.AspNetCore.Authentication.Negotiate(不在 Chrome 中,有时在 Edge 中,始终在 IE 中)?

ca9*_*3d9 8 asp.net iis kestrel-http-server asp.net-core blazor

我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!” 来自...\BlazorApp1\BlazorApp1\Shared\LoginDisplay.razor右上方的以下剃须刀组件 ( )。

<AuthorizeView>
    Hello, @context.User.Identity.Name!
</AuthorizeView>
Run Code Online (Sandbox Code Playgroud)

如果使用 Kestrel 运行,则不会显示该消息。所以我尝试了以下步骤使其在 Kestrel 中工作。

  1. 导入 NuGet 包 Microsoft.AspNetCore.Authentication.Negotiate

  2. 添加以下代码ConfigureService()Startup.cs

    services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
Run Code Online (Sandbox Code Playgroud)
  1. 添加以下代码Configure()Startup.cs。它们被添加到app.UseRouting();和之间app.UseEndpoints(...
            app.UseAuthentication();
            app.UseAuthorization();
Run Code Online (Sandbox Code Playgroud)

它仍然不显示 Hello 消息。我读到“允许匿名请求。使用 ASP.NET Core 授权来挑战匿名身份验证请求。” 文档中,所以我做了以下操作来禁用匿名请求。

在 中_Host.cshtml,在 之后添加了以下几行@namespace BlazorApp1.Pages

@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
Run Code Online (Sandbox Code Playgroud)

但是,消息还是不显示?这是否意味着授权不起作用?


更新:

我将文件更新...\BlazorApp1\BlazorApp1\Shared\LoginDisplay.razor

<AuthorizeView>
    <Authorized>
        Hello, @context.User.Identity.Name!
    </Authorized>
    <NotAuthorized>
        You are not authorized to view that page...
    </NotAuthorized>
</AuthorizeView>
Run Code Online (Sandbox Code Playgroud)

它显示“您无权查看该页面...”。似乎 Windows 身份验证不起作用?


更新2:

文档中提到了以下内容。

Windows 环境配置 Microsoft.AspNetCore.Authentication.Negotiate 组件执行用户模式身份验证。服务主体名称 (SPN) 必须添加到运行服务的用户帐户,而不是计算机帐户。setspn -S HTTP/mysrevername.mydomain.com myuser在管理命令 shell 中执行。

我尝试在家里的个人电脑上的管理员 powershell 控制台中运行以下命令。

setspn -S HTTP/mypcname myusername
Run Code Online (Sandbox Code Playgroud)

然而,它得到了错误

PS C:\WINDOWS\system32> setspn -S HTTP/desktop8930 nkucw
Ldap Error(0x51 -- Server Down): ldap_connect
Failed to retrieve DN for domain "" : 0x00000051
Warning: No valid targets specified, reverting to current domain.
FindDomainForAccount: Call to DsGetDcNameWithAccountW failed with return value 0x0000054B
Unable to locate account nkucw
Run Code Online (Sandbox Code Playgroud)

这是输出:(它在日志中显示“授权成功。”几次,但最后一次显示授权失败)

信息:Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
      用户资料可用。使用“C:\Users\nkucw\AppData\Local\ASP.NET\DataProtection-Keys”作为密钥存储库和 Windows DPAPI 来加密静态密钥。
信息:Microsoft.Hosting.Lifetime[0]
      现在收听:https://localhost:5001
信息:Microsoft.Hosting.Lifetime[0]
      现在监听:http://localhost:5000
信息:Microsoft.Hosting.Lifetime[0]
      应用程序启动。按 Ctrl+C 关闭。
信息:Microsoft.Hosting.Lifetime[0]
      托管环境:开发
信息:Microsoft.Hosting.Lifetime[0]
      内容根路径:C:\Users\nkucw**strong text**\source\repos\TestPS\BlazorApp1
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求启动 HTTP/1.1 GET https://localhost:5001/
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      授权失败。
信息:Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[12]
      AuthenticationScheme:协商受到质询。
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 135.0172ms 401 内完成
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求启动 HTTP/1.1 GET https://localhost:5001/
信息:Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[0]
      没有任何
信息:Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[1]
      不完整的协商握手,发送额外的 401 协商挑战。
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 16.6473ms 401 内完成
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求启动 HTTP/1.1 GET https://localhost:5001/
信息:Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[0]
      没有任何
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      授权成功。
信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      执行端点'/_Host'
信息:Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      路由与 {page = "/_Host"} 匹配。执行页面 /_Host
信息:Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      执行隐式处理程序方法 - ModelState 有效
信息:Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      执行隐式处理程序方法,返回结果 Microsoft.AspNetCore.Mvc.RazorPages.PageResult。
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
      授权成功。
信息:Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      在 206.51090000000002ms 内执行页面 /_Host
信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      执行端点'/_Host'
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 270.6847ms 200 text/html 内完成;字符集=utf-8
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求启动 HTTP/1.1 GET https://localhost:5001/css/bootstrap/bootstrap.min.css
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求开始 HTTP/1.1 GET https://localhost:5001/css/site.css
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求启动 HTTP/1.1 GET https://localhost:5001/_framework/blazor.server.js
信息:Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
      文件 /css/site.css 未被修改
信息:Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
      文件 /_framework/blazor.server.js 未修改
信息:Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
      文件 /css/bootstrap/bootstrap.min.css 未被修改
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 26.105700000000002ms 304 text/css 内完成
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 21.6629ms 304 application/javascript 内完成
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 21.6629ms 304 text/css 内完成
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求开始 HTTP/1.1 GET https://localhost:5001/css/open-iconic/font/css/open-iconic-bootstrap.min.css
信息:Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
      文件 /css/open-iconic/font/css/open-iconic-bootstrap.min.css 未修改
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 7.1119ms 内完成 304 text/css
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求开始 HTTP/1.1 POST https://localhost:5001/_blazor/negotiate text/plain;charset=UTF-8 0
信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      执行端点'/_blazor/negotiate'
信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      执行端点'/_blazor/negotiate'
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 22.780900000000003ms 200 application/json 内完成
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求开始 HTTP/1.1 GET https://localhost:5001/css/open-iconic/font/fonts/open-iconic.woff
信息:Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
      文件 /css/open-iconic/font/fonts/open-iconic.woff 没有被修改
信息:Microsoft.AspNetCore.Hosting.Diagnostics[1]
      请求开始 HTTP/1.1 GET https://localhost:5001/_blazor?id=ase9fodeUXavBCDTwk1Suw
信息:Microsoft.AspNetCore.Hosting.Diagnostics[2]
      请求在 7.676900000000001ms 304 application/font-woff 内完成
信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      执行端点'/_blazor'
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      授权失败。

更新3:

发现它在 Edge 中有效,但在 Chrome 中无效。是服务器端 Blazor 的错误吗?

更新4:

即使使用Edge,不断刷新页面表明它有时可能无法获得身份验证。

Ata*_*hev 6

我在解决类似问题时发现了您的问题。我想我知道您的问题的答案 - 您可以使用一个简单的中间件来挑战身份验证并显示登录信息。

  1. 在你的 Configure 方法中添加这个:
app.UseMiddleware<ValidateAuthentication>();
Run Code Online (Sandbox Code Playgroud)
  1. 这是中间件本身:
internal class ValidateAuthentication : IMiddleware
{
  public async Task InvokeAsync(HttpContext context, RequestDelegate next)
  {
    if (context.User.Identity.IsAuthenticated)
        await next(context);
    else
        await context.ChallengeAsync();
  }
}
Run Code Online (Sandbox Code Playgroud)
  1. 在 ConfigureServices 中:
 services.AddSingleton<ValidateAuthentication>();
Run Code Online (Sandbox Code Playgroud)

您不应该需要构造函数。

  • 这应该在文档中 https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.0&amp;tabs=visual-studio#kestrel (2认同)

Bra*_*ang 0

根据您的描述,我猜您可能启用了使用当前用户名和密码设置的 IE 用户身份验证自动登录,因为 chrome 也使用此设置来避免显示 Windows 身份验证的弹出窗口。

我建议您可以尝试按照以下步骤修改设置并重试。

1.打开IE,找到internet选项。

在此输入图像描述

2.修改用户认证方式,提升为用户名和密码

在此输入图像描述

3.关闭ie和chrome再试。