在 Angular 应用程序中针对本地 AD 进行身份验证

Joh*_*ull 5 c# asp.net-core identityserver4 angular

我一直在开发带有 .NET Core 后端(服务)的 Angular 应用程序。任务是启用集成身份验证,即使其与本地用户无缝协作,因此我登录到我的(连接到本地 AD)计算机一次,Web 应用程序就会让我进入,而无需再次登录。我们一直在使用 Identity Server 4 并打算使用它来实现此场景。

官方网站上有一些关于 Windows 身份验证(例如针对 Active Directory)的文档:http://docs.identityserver.io/en/latest/topics/windows.html但它没有解释太多。根据我的信息,为了使此方案发挥作用,浏览器使用 Kerberos 或 NTLM。IS4 文档中没有提到它们。我不了解如何获取本地凭据以及 IS4 如何“知道”用户属于 AD?如何确保只有特定域的用户才能访问我的应用程序?

我在这里找到了一些工作内容https://github.com/damienbod/AspNetCoreWindowsAuth但问题仍然相同。尽管我能够使用本地帐户访问该应用程序,但我不了解流程。

我希望用户在本地网络中使用该应用程序时无需输入登录名/密码即可登录该应用程序(一旦他已经登录到 Windows)。这是可以实现的吗?

Zin*_*nov 4

身份服务器旨在充当身份提供者,如果您需要与您的 AD 对话,您应该看到他们建议使用 IAuthenticationSchemeProvider 的联合网关架构。Identity Server 充当端点并与您的 AD 进行对话。

这是链接:联合网关

您可以控制以编程方式访问您的 AD 并传递正确的凭据以获得身份验证。该步骤应该在您的身份服务器中完成。通过身份验证后,您应该会再次重定向到您的应用程序。关于你的最后一个问题,答案是肯定的,如果你的网站托管在 Intranet 上并且你可以访问你的 AD,你不需要捕获你的凭据作为用户输入,你可以像我说的那样以编程方式访问 AD 。

下面是我用来连接活动目录的代码

在ExternalController类上,当您使用IdentityServer时,您会得到以下结果:(我不记得我对原始代码进行了多少更改,但您应该明白)

    /// <summary>
    /// initiate roundtrip to external authentication provider
    /// </summary>
    [HttpGet]
    public async Task<IActionResult> Challenge(string provider, string returnUrl)
    {
        if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/";

        // validate returnUrl - either it is a valid OIDC URL or back to a local page
        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)
        {
            // user might have clicked on a malicious link - should be logged
            throw new Exception("invalid return URL");
        }

        if (AccountOptions.WindowsAuthenticationSchemeName == provider)
        {
            // windows authentication needs special handling
            return await ProcessWindowsLoginAsync(returnUrl);
        }
        else
        {
            // start challenge and roundtrip the return URL and scheme 
            var props = new AuthenticationProperties
            {
                RedirectUri = Url.Action(nameof(Callback)),
                Items =
                {
                    { "returnUrl", returnUrl },
                    { "scheme", provider },
                }
            };

            return Challenge(props, provider);
        }
    }

private async Task<IActionResult> ProcessWindowsLoginAsync(string returnUrl)
        {
            // see if windows auth has already been requested and succeeded
            var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName);
            if (result?.Principal is WindowsPrincipal wp)
            {
                // we will issue the external cookie and then redirect the
                // user back to the external callback, in essence, testing windows
                // auth the same as any other external authentication mechanism
                var props = new AuthenticationProperties()
                {
                    RedirectUri = Url.Action("Callback"),
                    Items =
                    {
                        { "returnUrl", returnUrl },
                        { "scheme", AccountOptions.WindowsAuthenticationSchemeName },
                    }
                };

                var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName);
                id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name));
                id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));

                // add the groups as claims -- be careful if the number of groups is too large
                if (AccountOptions.IncludeWindowsGroups)
                {
                    var wi = wp.Identity as WindowsIdentity;
                    var groups = wi.Groups.Translate(typeof(NTAccount));
                    var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value));
                    id.AddClaims(roles);
                }

                await HttpContext.SignInAsync(
                    IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme,
                    new ClaimsPrincipal(id),
                    props);
                return Redirect(props.RedirectUri);
            }
            else
            {
                // trigger windows auth
                // since windows auth don't support the redirect uri,
                // this URL is re-triggered when we call challenge
                return Challenge(AccountOptions.WindowsAuthenticationSchemeName);
            }
        }
Run Code Online (Sandbox Code Playgroud)

如果您想使用Azure AD,我建议您阅读这篇文章: https://damienbod.com/2019/05/17/updating-microsoft-account-logins-in-asp-net-core-with-openid -连接和天蓝色活动目录/