c# - WindowsIdentity:异常:System.Security.SecurityException:用户名或密码不正确
问题描述
在 Windows Server 2012 R2 上,我们希望通过 C# 代码从 Active Directory 中获取用户的安全组。该应用程序是一个 ASP.NET MVC5 项目,由 IIS 托管。
首先,我们通过 查询 Active Directory 中的用户帐户UserPrincipal.FindByIdentity(...)
。这很好用。接下来,我们使用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(...)
成功了。一些帐户正在工作。某些帐户无法使用。我找不到工作账户和非工作账户之间的区别。
问题:谁知道我做错了什么?
补充说明:
- Applicationpool 标识为:LocalSystem
- 在 Web.config 中,有以下条目:
<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... [...] }
解决方案
我真的不知道这是否有帮助,但在某个地方我发现了这个:
- 如果 IIS 设置为允许匿名访问,您可以使用 userPrincipleName 格式 (
username@domain
)。 - 如果在 IIS 中未启用匿名访问,您需要使用表单中的用户名
domain\username
。
似乎很奇怪,尽管对于某些帐户 UPN 有效,而对于其他帐户则无效..
推荐阅读
- ps - 跟踪同名进程
- javascript - 为什么鼠标离开区域时元素没有消失?
- android - 创建新虚拟设备时丢失 avd 文件中的数据 - Android Studio
- android - 为什么 SurfaceFlinger 在其主函数中注册了 GraphicsAllocatorService 和 DisplayService?
- python - Ray Tune 增加内存使用率
- c++ - 一个关于描述符和反射的protobuf问题
- generative-adversarial-network - 为什么 c1 在 InfoGAN 中捕获数字类型?
- python - 在 Flask 或 FASTAPI 中处理 Webhook
- r - R:正确使用 fct_infreq 函数
- python - 如何将 GET 响应转换为 pandas 数据框?