在Windows Server 2012 R2上,我们想通过C#代码从Active Directory获取用户的安全组。该应用程序是一个ASP.NET MVC5项目,并由IIS托管。
首先,我们通过从Active Directory查询用户帐户。这很好用。接下来,我们使用类从活动目录中查询安全组。我们使用类,因为响应非常快。
以下是代码:
问题:当实例化
首先,我们通过从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... [...] }