从调试

时间:2016-05-13 18:17:33

标签: c# asp.net active-directory

我有一个很大程度上依赖于AD身份验证的ASP.NET应用程序。我们最近推出了一项服务,该服务过去与应用程序在同一解决方案中存在于自己的解决方案中,因此我们可以单独维护它们,而不会影响依赖服务的用户,比如说,我们只需要进行代码更改影响了应用程序的UI端。

但这对我来说是一个有趣的问题。当我调试时,我的应用程序的本地副本指向服务的远程实例,该应用程序的环境副本也使用该实例。当我尝试使用本地应用程序验证用户成员身份时 - >远程服务调用,它失败,出现以下异常:

  

System.Runtime.InteropServices.COMException(0x8007200A):The   指定的目录服务属性或值不存在。

     

at System.DirectoryServices.DirectoryEntry.Bind(Boolean   throwIfFail)在System.DirectoryServices.DirectoryEntry.Bind()中   在System.DirectoryServices.DirectoryEntry.get_SchemaEntry()at   System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(的DirectoryEntry   德)   System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(的DirectoryEntry   ctxBase,Boolean ownCtxBase,String username,String password,   ContextOptions选项)at   System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(的DirectoryEntry   进入)   System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()   在   System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()   在   System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()   在   System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()   在   System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext   context,Type principalType,Nullable`1 identityType,String   identityValue,DateTime refDate)at   System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext   context,String identityValue)at   ******************。******************。************ ****** .IsUserMemberOfGroup(String userName,String groupName)

当我尝试对同一组中的同一个用户进行身份验证,但是使用网络浏览器点击远程服务器上的应用程序然后点击远程服务时,它就像一个蛤蜊一样高兴。

我正在使用的代码似乎很简单。它必须与我的机器如何呼叫有关,但如果我可以解决它,我会被淹没。

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);
}

1 个答案:

答案 0 :(得分:0)

你过早剥离域名,所以你并没有真正尝试不同的第二次机会。

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);
}

实际上我注意到StackTrace中有一个DoDomainInit(你的本地机器可能在不同的域中,或者身份字符串参数在远程盒子上的行为可能不同)。请记住,如果您的计算机不属于域,则必须指定user / pswd。

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

同时检查是否可以通过将本地计算机Application Pool Identity更改为在网络服务下运行来修复它,因为错误类似于此issue