3

以下は私のローカル開発ボックスでうまく機能します。ただし、Webサーバーに移動すると失敗し、エラーもログに記録されません。

public static List<string> getAuthorizationGrps(string userName)
    {
        List<string> grps = new List<string>();

        try
        {
            PrincipalSearchResult<Principal> groups = UserPrincipal.Current.GetGroups();
            IEnumerable<string> groupNames = groups.Select(x => x.SamAccountName);
            foreach (var name in groupNames)
            {
                grps.Add(name.ToString());
            }
            return grps;
        }
        catch (Exception ex)
        {
            Log.WriteLog("Error in retriving form data: " + ex.Message);
        }
    }

グループをクエリするためにWebサーバーに設定する必要のあるアクセス許可はありますか?ローカルとWebサーバーの両方で問題なく現在のユーザーを取得できます。

どんなアイデアでも大歓迎です、私はこれを2日間戦っています。

4

2 に答える 2

1

約6か月前、同様の問題が発生しました。私たちのコードはUserPrincipal.Current.GetGroups()を呼び出し、foreachループでオブジェクトを列挙していました。ある朝まで、テストと本番環境で問題なく動作しました。1人の共同作業者が、コードの実行時に例外が発生し続けました。groupNamesオブジェクトを列挙すると、IndexOutOfRangeExceptionのスローが開始されました。1時間後、何が問題になっているのか理解できなかったので、ここの2番目の回答と同様に、ADSI呼び出しを行うストアドプロシージャと呼ばれる応急修理を追加しました。きれいではありませんが、一度も問題が発生したことはありません。

于 2012-08-08T02:06:42.630 に答える
0

これがあなたの環境だと思います

Web browser --> Web Server --> Domain Controller

Web Browser and Web Serverまたはを同じマシンで実行しているWeb Server and Domain Controller場合を除き、上記のコードを機能させるには、Kerberos委任を設定する必要があります。同じマシンでWebブラウザとWebサーバーを実行しているため、開発ボックスが機能していると思います。

GoogleからIISおよびASP.NETのKerberos委任を構成する方法を説明する多数の記事を簡単に見つけることができます。これが1つの例です。ここでは詳細を説明しません。重要なのは、ASP.NETアプリケーションがクライアントの資格情報を偽装し、そのクライアントの資格情報を使用してActiveDirectoryにクエリを実行しようとしていることです。委任が適切に設定されていない場合、Windowsは、偽装された資格情報がネットワークにアクセスできないと見なします。あなたの場合、ドメインコントローラーにアクセスすることはできません。これはセキュリティ対策です。サーバーに許可が明示的に付与されていない限り、サーバーがネットワーク上のエンドユーザーに代わって処理を実行できないようにするだけです。

別の解決策は、コードを変更することです。したがって、GetGroupsを呼び出す前に、偽装を元に戻し、IISAppPoolアカウントになります。AppPoolアカウントが、Active Directoryを読み取るのに十分なアクセス許可を持つドメインアカウントとして構成されている場合は、ActiveDirectoryにユーザーのグループを照会できます。

これについて話しているブロブがあります。これは、Kerberos委任を設定しなくても機能するはずのコードです。私はそれをテストしませんでした。

public static List<string> getAuthorizationGrps(string userName)          
{          
    List<string> grps = new List<string>();          

    try          
    {
        var currentUser = UserPrincipal.Current;
        RevertToSelf();             
        PrincipalSearchResult<Principal> groups = currentUser.GetGroups();          
        IEnumerable<string> groupNames = groups.Select(x => x.SamAccountName);          
        foreach (var name in groupNames)          
        {          
            grps.Add(name.ToString());          
        }          
        return grps;          
    }          
    catch (Exception ex)          
    {          
        Log.WriteLog("Error in retriving form data: " + ex.Message);          
    }          
}      
于 2012-08-08T05:29:32.873 に答える