0

特定のユーザーの AD からグループを返すコードがあります。私の開発ボックスでローカルにうまく機能します。Web サーバーで実行しようとすると、コードは完了しませんが、エラーがスローされてから戻ります。これは権限に関係している可能性があるので、コードが偽装を元に戻すグループの取得が完了したら、管理者アカウントを偽装するためのピースを追加しました。このコードはエラーをスローしませんが、グループのリストも返しません。

public static List<GroupPrincipal> GetUserGroups(string userName)
{

    bool isImper = impersonateValidUser("user", "domain", "password");
    List<GroupPrincipal> result = new List<GroupPrincipal>();

    // establish domain context
    PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain,"WYSD");

    // find your user
    UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);

    // if found - grab its groups
    if (user != null)
    {
        PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();

        // iterate over all groups
        foreach (Principal p in groups)
        {
            // make sure to add only group principals
            if (p is GroupPrincipal)
            {
                result.Add((GroupPrincipal)p);
            }
        }
    }
    undoImpersonation();
    try
    {
        return result;
    }
    catch (Exception ex)
    {
        Log.WriteLog("Error in retriving form data: " + ex.Message);
        Thread.Sleep(1000);
        return GetUserGroups(userName);
    }
}

キャッチ内のThread.Sleepは、現時点で .NET 4.0 の問題の回避策として使用されています。なりすましを使用して、または使用せずにコードをローカルで使用すると、正常に動作します。なりすましのコードは次のとおりです。

public static bool impersonateValidUser(String userName, String domain, String password)
{
    System.Security.Principal.WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;
    if(userName.Contains("\\")){
        userName = userName.Substring(userName.LastIndexOf("\\") + 1);
    }
    if (LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
    {
        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
        {
            tempWindowsIdentity = new System.Security.Principal.WindowsIdentity(tokenDuplicate);
            impersonationContext = tempWindowsIdentity.Impersonate();
            if (impersonationContext != null)
                return true;
            else
                return false;
        }
        else
            return false;
    }
    else
        return false;
}
public static void undoImpersonation()
{
    impersonationContext.Undo();
}


#region | Property |
// property getters/setters
public string DomainName { get; set; }
public string LoginPath { get; set; }
public string LoginUsername { get; set; }
public string LoginPassword { get; set; }
public System.DirectoryServices.AuthenticationTypes AuthenticationType { get; set; }
public System.DirectoryServices.DirectoryEntry Ad { get { return Ad; } set { Ad = value; } }
#endregion

#region | Impersonation via interop |
//need to import from COM via InteropServices to do the impersonation when saving the details
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
static System.Security.Principal.WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
public extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
#endregion

問題は、まずなりすましが必要かどうか、そうでない場合はなぜコードが機能しないのかということだと思います。第二に、なりすましが必要な場合、なぜ自分のグループを元に戻せないのですか?

4

0 に答える 0