简体   繁体   English

从调试远程调用中检索AD组成员身份失败

[英]Retrieving AD group membership failing on remote call from debug

I have an ASP.NET application which relies heavily on AD authentication. 我有一个严重依赖AD身份验证的ASP.NET应用程序。 We recently broke out a service which used to live in the same solution as the application into its own solution, so that we could maintain them seperately and not impact users who rely on the service when, say, we needed to make code changes which only impacted the UI side of the application. 最近,我们将一项曾经与该应用程序存在于同一解决方案中的服务分解为自己的解决方案,以便我们可以单独维护它们,而不会影响依赖该服务的用户,例如,当我们需要进行代码更改时,影响了应用程序的用户界面。

This has lead to an interesting issue for me though. 这给我带来了一个有趣的问题。 When I debug, I have my local copy of the application pointing to a remote instance of the service, which is also used by the environment copy of the application. 调试时,我将应用程序的本地副本指向服务的远程实例,该实例也由应用程序的环境副本使用。 When I attempt to authenticate user membership using the local app -> remote service call, it fails with the following exception: 当我尝试使用本地应用程序->远程服务调用来验证用户成员身份时,它失败,但出现以下异常:

System.Runtime.InteropServices.COMException (0x8007200A): The specified directory service attribute or value does not exist. System.Runtime.InteropServices.COMException(0x8007200A):指定的目录服务属性或值不存在。

at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() 在System.DirectoryServices.DirectoryEntry.Bind()处的System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.get_SchemaEntry() at System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de) at System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase, Boolean ownCtxBase, String username, String password, ContextOptions options) at System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry entry) at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer() at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate) at System.DirectoryServices.AccountManagement 在System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de)的System.DirectoryServices.DirectoryEntry.get_SchemaEntry()处在System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase,布尔ownCtxBase,字符串用户名,字符串密码, )(位于System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry条目)处) )在System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext上下文,类型PrincipalType,Nullable`1 identityType,字符串identityValue,DateTime refDate)在System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(在System.DirectoryServices.AccountManagement .UserPrincipal.FindByIdentity(PrincipalContext context, String identityValue) at ******************.******************.******************.IsUserMemberOfGroup(String userName, String groupName) .UserPrincipal.FindByIdentity(PrincipalContext上下文,字符串identityValue)在******************。******************。 ******************。IsUserMemberOfGroup(字符串userName,字符串groupName)

When I attempt to authenticate the same user in the same group, but using a web browser to hit the app on the remote box which then hits the remote service, it's happy as a clam. 当我尝试对同一组中的同一用户进行身份验证,但使用Web浏览器在远程框中点击该应用程序,然后再点击该远程服务时,我感到很高兴。

The code I'm using seems trivially simple. 我正在使用的代码看起来很简单。 It must be something to do with how my machine is calling out, but I'll be dipped if I can work it out. 这一定与我的计算机如何发出声音有关,但如果可以解决,我会被浸入。

public static bool IsUserMemberOfGroup(string userName, string groupName)
{
    try
    {
        PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "XXX");

        var user = GetUser(userName, ctx);

        if (user == null)
        {
            Log4NetLogManager.LogError("Unable to find user " + userName);
            return false;
        }

        // find the group in question
        groupName = groupName.Replace("XXX\\", string.Empty);
        GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);

        if (group != null) return user.IsMemberOf(group);

        Log4NetLogManager.LogError("Unable to find group " + groupName);
        return false;
    }
    catch (Exception ex)
    {
        if (!ex.Message.Contains("Unknown error"))
        {
            Log4NetLogManager.LogException(string.Format("Error while checking if {0} is a member of {1}", userName, groupName), ex);
        }
        return false;
    }
}

private static UserPrincipal GetUser(string userName, PrincipalContext ctx)
{
    UserPrincipal user = null;
    userName = userName.Replace("XXX\\", string.Empty);

    try
    {
        user = UserPrincipal.FindByIdentity(ctx, userName);
    }
    catch
    {
    }

    return user ?? UserPrincipal.FindByIdentity(ctx, userName);
}

You're stripping the domain name too early, so you're not really trying a different second chance. 您太早剥离域名了,因此您并没有真正尝试其他的第二次机会。

private static UserPrincipal GetUser(string userName, PrincipalContext ctx)
{
    UserPrincipal user = null;

    try
    {
        user = UserPrincipal.FindByIdentity(ctx, userName);
    }
    catch (Exception exc1)
    {
        Log4NetLogManager.LogError("First chance: " + exc1.Message);
    }
    userName = userName.Replace("XXX\\", string.Empty);

    return user ?? UserPrincipal.FindByIdentity(ctx, userName);
}

In fact I've noticed that there is a DoDomainInit in the StackTrace (either your local machine could be in a different domain or the identity string parameter could behave differently on the remote box). 实际上,我已经注意到StackTrace中有一个DoDomainInit (本地计算机可能位于不同的域中,或者标识字符串参数在远程框中的行为可能有所不同)。 Remember that you have to specify user/pswd if your machine doesn't belong to the domain. 请记住,如果您的计算机不属于域,则必须指定user / pswd。

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "XXX", "ad_usr","ad_pswd");
var user = GetUser(userName, ctx);

Also check if it can be fixed it by changing your local machine Application Pool Identity to run under the Network Service, as the error is similar to this issue . 另外,还可以通过更改本地计算机“ 应用程序池标识”以使其在网络服务下运行来检查是否可以解决该问题 ,因为错误类似于此问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM