首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >.NET 4.5 UserPrincipal.FindByIdentity中的Bug (System.DirectoryServices.AccountManagement)

.NET 4.5 UserPrincipal.FindByIdentity中的Bug (System.DirectoryServices.AccountManagement)
EN

Stack Overflow用户
提问于 2012-09-26 19:26:20
回答 2查看 21K关注 0票数 30

在测试我们的.NET 4.0应用程序时,在.NET 4.5下,我们遇到了UserPrincipalFindByIdentity方法的问题。以下代码在.NET 4.0运行时工作,但在.NET 4.5下失败:

代码语言:javascript
运行
复制
[Test]
public void TestIsAccountLockedOut()
{
    const string activeDirectoryServer = "MyActiveDirectoryServer";
    const string activeDirectoryLogin = "MyADAccount@MyDomain";
    const string activeDirectoryPassword = "MyADAccountPassword";
    const string userAccountToTest = "TestUser@MyDomain";
    const string userPasswordToTest = "WRONGPASSWORD";

    var principalContext = new PrincipalContext(ContextType.Domain, activeDirectoryServer, activeDirectoryLogin, activeDirectoryPassword);

    var isAccountLockedOut = false;
    var isAuthenticated = principalContext.ValidateCredentials(userAccountToTest, userPasswordToTest, principalContext.Options);
    if (!isAuthenticated)
    {
        // System.DirectoryServices.AccountManagement.PrincipalOperationException : Information about the domain could not be retrieved (1355).
        using (var user = UserPrincipal.FindByIdentity(principalContext, IdentityType.UserPrincipalName, userAccountToTest))
        {
            isAccountLockedOut = (user != null) && user.IsAccountLockedOut();
        }
    }
    Assert.False(isAuthenticated);
    Assert.False(isAccountLockedOut);
}

下面是异常堆栈跟踪:

代码语言:javascript
运行
复制
System.DirectoryServices.AccountManagement.PrincipalOperationException : Information about the domain could not be retrieved (1355).
at System.DirectoryServices.AccountManagement.Utils.GetDcName(String computerName, String domainName, String siteName, Int32 flags)   at System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDomainInfo()   at 
System.DirectoryServices.AccountManagement.ADStoreCtx.get_DnsDomainName()   at System.DirectoryServices.AccountManagement.ADStoreCtx.GetAsPrincipal(Object storeObject, Object discriminant)   at 
System.DirectoryServices.AccountManagement.ADStoreCtx.FindPrincipalByIdentRefHelper(Type principalType, String urnScheme, String urnValue, DateTime referenceDate, Boolean useSidHistory)   at 
System.DirectoryServices.AccountManagement.ADStoreCtx.FindPrincipalByIdentRef(Type principalType, String urnScheme, String urnValue, DateTime referenceDate)   at 
System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)   at 
System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)   at 
System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)   

还有人看到并解决了这个问题吗?如果没有,是否有更好的方法来检查Active Directory帐户的IsAccountLockedOut状态?

作为参考,我们所有的测试机器都在同一个子网中。在不同的域功能模式下,运行Windows 2003、2008和2012的独立ActiveDirectory服务器(见下文)。代码在运行.NET 4.0的机器上工作,但在运行.NET 4.5的机器上却失败。

我们运行代码的三台.NET机器是:

  • 运行.NET 4.0的Windows 7
  • 运行.NET 4.5的Windows
  • 运行.NET 4.5的Windows 2012

我们尝试过的服务器是:

  • 将AD域功能模式设置为Windows 2000本机的Windows 2003
  • 将AD域功能模式设置为Windows 2003的Windows 2003
  • 将AD域功能模式设置为Windows 2000本机的Windows 2008
  • 将AD域功能模式设置为Windows 2003的Windows 2008
  • 将AD域功能模式设置为Windows 2008的Windows 2008
  • 将AD域功能模式设置为Windows 2012的Windows 2012

所有这些Active服务器都配置为一个简单的单一林,并且客户端计算机不是域的一部分。除了测试此行为之外,它们不用于任何其他函数,并且除了之外,没有运行任何其他功能。

编辑-2012年10月9日

感谢所有回复的人。下面是一个演示问题的C#命令行客户端,以及一个短期的解决方案,我们发现它不需要我们更改有关Active和DNS配置的任何内容。该异常似乎只与PrincipalContext实例一起引发一次。我们包括了.NET 4.0计算机(Windows7)和.NET 4.5计算机(Windows )的输出。

代码语言:javascript
运行
复制
using System;
using System.DirectoryServices.AccountManagement;

namespace ADBug
{
    class Program
    {
        static void Main(string[] args)
        {
            const string activeDirectoryServer = "MyActiveDirectoryServer";
            const string activeDirectoryLogin = "MyADAccount";
            const string activeDirectoryPassword = "MyADAccountPassword";
            const string validUserAccount = "TestUser@MyDomain.com";
            const string unknownUserAccount = "UnknownUser@MyDomain.com";

            var principalContext = new PrincipalContext(ContextType.Domain, activeDirectoryServer, activeDirectoryLogin, activeDirectoryPassword);

            // .NET 4.0 - First attempt with a valid account finds the user
            // .NET 4.5 - First attempt with a valid account fails with a PrincipalOperationException
            TestFindByIdentity(principalContext, validUserAccount, "Valid Account - First Attempt");
            // Second attempt with a valid account finds the user
            TestFindByIdentity(principalContext, validUserAccount, "Valid Account - Second Attempt");
            // First attempt with an unknown account does not find the user
            TestFindByIdentity(principalContext, unknownUserAccount, "Unknown Account - First Attempt");
            // Second attempt with an unknown account does not find the user (testing false positive)
            TestFindByIdentity(principalContext, unknownUserAccount, "Unknown Account - Second Attempt");
            // Subsequent attempt with a valid account still finds the user
            TestFindByIdentity(principalContext, validUserAccount, "Valid Account - Third Attempt");
        }

        private static void TestFindByIdentity(PrincipalContext principalContext, string userAccountToTest, string message)
        {
            var exceptionThrown = false;
            var userFound = false;
            try
            {
                using (var user = UserPrincipal.FindByIdentity(principalContext, IdentityType.UserPrincipalName, userAccountToTest))
                {
                    userFound = (user != null);
                }
            }
            catch (PrincipalOperationException)
            {
                exceptionThrown = true;
            }
            Console.Out.WriteLine(message + " - Exception Thrown  = {0}", exceptionThrown);
            Console.Out.WriteLine(message + " - User Found = {1}", userAccountToTest, userFound);
        }
    }
}

.NET 4.0输出

代码语言:javascript
运行
复制
Valid Account - First Attempt - Exception Thrown  = False
Valid Account - First Attempt - User Found = True
Valid Account - Second Attempt - Exception Thrown  = False
Valid Account - Second Attempt - User Found = True
Unknown Account - First Attempt - Exception Thrown  = False
Unknown Account - First Attempt - User Found = False
Unknown Account - Second Attempt - Exception Thrown  = False
Unknown Account - Second Attempt - User Found = False
Valid Account - Third Attempt - Exception Thrown  = False
Valid Account - Third Attempt - User Found = True

.NET 4.5输出

代码语言:javascript
运行
复制
Valid Account - First Attempt - Exception Thrown  = True
Valid Account - First Attempt - User Found = False
Valid Account - Second Attempt - Exception Thrown  = False
Valid Account - Second Attempt - User Found = True
Unknown Account - First Attempt - Exception Thrown  = False
Unknown Account - First Attempt - User Found = False
Unknown Account - Second Attempt - Exception Thrown  = False
Unknown Account - Second Attempt - User Found = False
Valid Account - Third Attempt - Exception Thrown  = False
Valid Account - Third Attempt - User Found = True
EN

Stack Overflow用户

发布于 2017-03-14 10:01:23

在将.net框架从4.0升级到4.5之后,我也遇到了同样的问题,我已经将框架升级到.net 4.5.1,并且它成功了。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12608971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档