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

How to use Windows authentication on ASP.NET Core subpath only?

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

我的问题是当我添加

services.AddAuthentication().AddNegotiate()

我收到一个错误

The Negotiate Authentication handler cannot be used on a server that directly supports Windows Authentication.

这导致我添加 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>

错误消失了。但是,现在每个请求都会弹出 Windows 身份验证。

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

所以这可能吗?我该如何做到这一点只有 /testendpoint 会要求 Windows 身份验证,而应用程序的其余部分将与我在 [=32= 中配置的任何其他身份验证一起使用] 核心应用程序?

为了通过 Windows 身份验证保护某个 page/action 方法,请在操作方法 Authorize 属性中指定相应的身份验证方案。

[Authorize(AuthenticationSchemes = IISServerDefaults.AuthenticationScheme)]
public IActionResult UsingWindowsAuthentication()

确保在您的网站上启用 Windows authentication
为了使用其他身份验证方案,例如“个人账户”,也开启了匿名认证。

不能使用 Windows 身份验证的控制器 and/or 操作方法指定了默认方案。
例如,对于使用开箱即用的“个人帐户”身份验证类型作为默认身份验证方法的 ASP.NET Core MVC 项目,即 Identity.Application.

[Authorize(AuthenticationSchemes = "Identity.Application")]
public IActionResult Index()

请参阅documentation了解如何设置和配置多个身份验证方案。

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

我们有一个应用程序架构,将在名为 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));

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

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

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