WindowsIdentity: 异常: System.Security.SecurityException: 用户名或密码不正确。

3
在Windows Server 2012 R2上,我们想通过C#代码从Active Directory获取用户的安全组。该应用程序是一个ASP.NET MVC5项目,并由IIS托管。
首先,我们通过从Active Directory查询用户帐户。这很好用。接下来,我们使用类从活动目录中查询安全组。我们使用类,因为响应非常快。
以下是代码:
var lDomain = "MyDomain";
var lSamAccountName = "Simon";

using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, lDomain))
{
    // Get User Account from Active Directory
    using (UserPrincipal lUserPrincipal = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, lSamAccountName))
    {
        var lUpn = lUserPrincipal.UserPrincipalName; // get UPN

        // get Security Groups of the user
        using (WindowsIdentity lWindowsIdentity = new WindowsIdentity(lUpn)) // Exception: System.Security.SecurityException: The user name or password is incorrect
        {
            var lGroups = lWindowsIdentity.Groups;
        }
    }
}

问题:当实例化 WindowsIdentity 类(并传递 UPN)时,会发生异常。
Upn: 'simon@MyDomain' Exception: System.Security.SecurityException: The user name or password is incorrect.
at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn, SafeAccessTokenHandle& safeTokenHandle)
at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName, String type)
at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName)
at ...

这很奇怪,因为使用 UserPrincipal.FindByIdentity(...) 查询是成功的。有些账户可以正常工作,但有些账户不能正常工作。我无法找到工作和不工作的账户之间的差异。

问题:谁知道我做错了什么?

附加说明:

  • The Applicationpool Identity is: LocalSystem
  • In the Web.config, there is the following entry: <identity impersonate="false" />
  • When I query the groups by the following alternative, then no exception occurs and the result is satisfying. That´s curious:

    var lResult = new List<SecurityIdentifier>();
    DirectorySearcher lDirectorySearcher = new DirectorySearcher();
    lDirectorySearcher.Filter = string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)(distinguishedName={0}))", lUserPrincipal.DistinguishedName); // for the object lUserPrincipal, look @ code above
    lDirectorySearcher.SearchScope = SearchScope.Subtree;
    SearchResult lSearchResult = lDirectorySearcher.FindOne();
    
    DirectoryEntry lDirectoryEntry = lSearchResult.GetDirectoryEntry();
    
    lDirectoryEntry.RefreshCache(new string[] { "tokenGroups" });
    
    // get groups
    for (int i = 0; i < lDirectoryEntry.Properties["tokenGroups"].Count; i++)
    {
        SecurityIdentifier lSid = new SecurityIdentifier((byte[])lDirectoryEntry.Properties["tokenGroups"][i], 0);
        lResult.Add(lSid);
    
        // Translate into NTAccount to get Domain and SAMAccountname etc...
        [...] 
    }
    
3个回答

1

我真的不知道这是否有所帮助,但是在某个地方我找到了这个:

  • 如果IIS设置为允许匿名访问,则可以使用userPrincipleName格式(username@domain)。
  • 如果IIS未启用匿名访问,则需要使用domain\username格式的用户名。

似乎很奇怪,因为对于某些帐户,UPN有效,而对于其他帐户则无效。


感谢您的提示。在这个Web应用程序中,启用了匿名身份验证,以便能够显示自定义登录页面。不幸的是,您发布的答案并没有集中关注我的问题。 - Simon

0

解决方案1:

使用ADSI Edit(通过MMC.exe)手动填充所需Windows服务帐户的userPrincipalName属性。

userPrincipalName的格式为

<username>@<fully_qualified_domain_name>

例如,对于上面的示例日志行,预期的UPN值应为:

goodadmin@example.com

在尝试使用服务帐户凭据之前,请允许几分钟进行Active Directory复制。

解决方案2:

确保Active Directory服务帐户信息在本地BEMS主机上具有必要的权限,如本地管理员作为服务登录

确保输入的Active Directory服务帐户信息实际上是有效的。例如,请确保正确输入密码并且该帐户未在Active Directory中被锁定。

确保Active Directory服务帐户信息具有必要的Active Directory组权限。

RTCUniversalReadOnlyAdmins

0

在这里,您可以找到如何基于UserPrincipal获取组的方法。

如何从DOMAIN\user格式的用户名创建WindowsIdentity/WindowsPrincipal

    // find all groups the user is member of (the check is recursive).
    // Guid != null check is intended to remove all built-in objects that are not really AD gorups.
    // the Sid.Translate method gets the DOMAIN\Group name format.
    var userIsMemberOf = p.GetAuthorizationGroups().Where(o => o.Guid != null).Select(o => o.Sid.Translate(typeof(NTAccount)).ToString());

    // use a HashSet to find the group the user is member of.
    var groups = new HashSet<string>(userIsMemberOf), StringComparer.OrdinalIgnoreCase);
    groups.IntersectWith(groupNames);

我知道GetAuthorizationGroups,但它太慢了。在许多环境中进行了测试,但没有回答我的问题。 - Simon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接