在Windows Server 2012 R2上,我们希望通过C#代码从Active Directory中获取用户的安全组。该应用程序是一个ASP.NET MVC5项目,由IIS托管。
首先,我们通过UserPrincipal.FindByIdentity(...)
从Active Directory中查询用户帐户。很好接下来,我们使用WindowsIdentity
类从活动目录中查询安全组。我们使用类WindowsIdentity
是因为响应速度非常快。
代码如下:
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(...)
的查询成功。一些帐户正在运行。有些帐户无法使用。我找不到正常帐户和无效帐户之间的区别。
问题:谁知道我在做什么错?
附加说明:
<identity impersonate="false" />
当我通过以下替代方式查询组时,则不会发生异常并且结果令人满意。很好奇:
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...
[...]
}
答案 0 :(得分:0)
我真的不知道这是否有帮助,但在某个地方我发现了这一点:
username@domain
)。domain\username
形式的用户名。对于某些帐户,UPN起作用,而对于另一些帐户则不起作用,这似乎很奇怪。
答案 1 :(得分:0)
解决方案1:
使用 ADSI编辑(通过 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
答案 2 :(得分:0)
在这里您可以找到如何基于UserPrincipal
How to create WindowsIdentity/WindowsPrincipal from username in DOMAIN\user format
// 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);