如何仅在 ASP.NET Core 子路径上使用 Windows 身份验证?

Pou*_*sen 5 windows-authentication .net-core asp.net-core

我尝试仅在 ASP.NET Core MVC 应用程序中的子路由上配置 Windows 身份验证。

我的问题是当我添加

services.AddAuthentication().AddNegotiate()
Run Code Online (Sandbox Code Playgroud)

我收到一个错误

协商身份验证处理程序不能在直接支持 Windows 身份验证的服务器上使用。

这导致我web.config按照文档的解释添加:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <location path="." inheritInChildApplications="false">
        <system.webServer>
            <security>
                <authentication>
                    <anonymousAuthentication enabled="false" />
                    <windowsAuthentication enabled="true" />
                </authentication>
            </security>
        </system.webServer>
    </location>
</configuration>
Run Code Online (Sandbox Code Playgroud)

然后错误就消失了。不过,现在每次请求都会弹出 Windows 身份验证。

我尝试将位置路径更改为,.testendpoint但随后会在基本路径处引发原始错误。

那么是否有可能,我该如何做到这一点,只/testendpoint要求 Windows 身份验证,而应用程序的其余部分将与我在 ASP.NET Core 应用程序中配置的任何其他身份验证一起使用?

MC9*_*000 9

只是想我会分享这些信息:

首先,仅仅因为您使用服务器管理器安装了Windows 身份验证,并不意味着它已在 IIS 中启用。默认情况下,它未启用。 您必须打开 IIS 管理器,单击您的服务器(不是网站 - 托管 IIS 的服务器计算机的名称)。然后单击“身份验证” - 您将看到“ Windows 身份验证”已禁用。启用它。现在它会起作用了。

在进行其他配置更改之前,请先检查其设置是否正确。如果针对 Windows 身份验证正确配置了 IIS,则 dotNet5 和 dotNet6 的默认项目将无需任何修改即可运行。


Pou*_*sen 6

使用端点路由的另一种方法:

我们有一个应用程序架构,将在整个应用程序中使用,称为 eavfw。

此处使用名为 login/ntlm 的自定义端点及其元数据new AuthorizeAttribute(NegotiateDefaults.AuthenticationScheme),仅允许有效的 Windows 身份验证用户访问。

然后,我们使用 AD 用户名在数据库中创建用户。

    endpoints.MapGet("/.auth/login/ntlm", async httpcontext =>
    {
        var loggger = httpcontext.RequestServices.GetRequiredService<ILogger<Startup>>();
        var windowsAuth = await httpcontext.AuthenticateAsync(NegotiateDefaults.AuthenticationScheme);
        
        if (!windowsAuth.Succeeded)
        {
            loggger.LogWarning("Not authenticated: Challening"); 
        }
        if (windowsAuth.Succeeded)
        {
            loggger.LogWarning("Authenticated");
           
            var name = string.Join("\\", windowsAuth.Principal.Claims.FirstOrDefault(c => c.Type.EndsWith("name")).Value.Split("\\").Skip(1));

            var context = httpcontext.RequestServices.GetRequiredService<DynamicContext>();
            var users = context.Set<SystemUser>();
            var user = await context.Set<SystemUser>().Where(c => c.PrincipalName == name).FirstOrDefaultAsync();
            if (user == null)
            {
                user = new SystemUser
                {
                    PrincipalName = name,
                    Name = name,
                    // Email = email,
                };
                await users.AddAsync(user);
                await context.SaveChangesAsync();
            }
             
            var principal = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] {                                  
                       new Claim(Claims.Subject,user.Id.ToString())
                    }, "ntlm"))
            {

            };

            await httpcontext.SignInAsync("ntlm",
                 principal, new AuthenticationProperties(
                            new Dictionary<string, string>
                            {
                                ["schema"] = "ntlm"
                            }));

            httpcontext.Response.Redirect("/account/login/callback");
        }
      

    }).WithMetadata(new AuthorizeAttribute(NegotiateDefaults.AuthenticationScheme));

Run Code Online (Sandbox Code Playgroud)

使用辅助身份验证 cookie,我们现在可以使我们的应用程序需要 Windows 身份验证的特定区域,它可以简单地依赖 Authorize("ntlm"),因为它会自动转发身份验证调用以检查是否已经登录,并且它作为上面端点中的登录调用的一部分实际上在重定向到一般帐户回调页面之前登录 eavfw.external,该页面将在eavfw从eavfw.externalcookie登录之前进行一些最终验证

            services.AddAuthentication().AddCookie("ntlm", o => {
                o.LoginPath = "/.auth/login/ntlm";
                o.ForwardSignIn = "eavfw.external";
                o.ForwardAuthenticate = "eavfw";
            });
Run Code Online (Sandbox Code Playgroud)

因此,有几种方法可以扩展和使用 auth core 中的身份验证系统,具体取决于应用程序的 MVC 框架的重量。

  • 超级有用且功能齐全,可以进行一些项目更改。这对我帮助很大。我使用的是 websockets,所以整个 MVC 的东西甚至不存在。能够使用中间件来处理这个问题正是我所需要的,并且似乎没有任何记录。谢谢你! (2认同)
  • @MuhammadNasir 对延迟表示歉意,直到现在才看到这一点。当然,这里有一个用于示例目的的存储库(不是完整的项目代码;但对本主题有用,相关代码就在那里):https://github.com/ensemblebd/sample-netcore5-ntlm-nomvc (2认同)