5

2 つの ASP.NET MVC 3 アプリケーションがあります。私は web.config を介して偽装を使用して、Active Directory にクエリを実行してユーザーの詳細を取得できるようにしています。アプリケーションは Windows 認証を使用し、匿名ユーザーを許可しません。1 つのアプリケーションは、ユーザーがタスクを実行する主要なアプリケーションです。もう 1 つは、ユーザーがアプリケーション 1 で他のユーザーのように見えるように設定できるようにするものです。

テスト ユーザーに次のエラーが表示されます。

SQL1092N  "<DOMAIN ID>" does not have the authority to perform the requested command.

これは、プライマリ アプリケーションからセカンダリ アプリケーションに Web 要求を送信した後に発生します。それを機能させるには、アプリケーションが偽装に使用する ID ではなく、実際のユーザーを偽装する要求を作成する必要がありました。これは実際に私が投稿して回答した SO の質問です。それはここにあります: WebRequest を介して MVC アクションを呼び出し、Active Directory を介して要求を検証するにはどうすればよいですか?

そのコードの最後で、次のように呼び出します。

impersonationContext.Undo();

この Web 要求が発生した後で、プライマリ アプリケーションがデータベースにアクセスしようとしましたが、上記の呼び出しによってアプリケーションの偽装が取り消されたように見えるため、ユーザーがデータベース接続を開く操作を実行しようとすると失敗します。少なくとも、それは頭をぶつけた後の私の作業理論です.

私の質問は、アプリケーションの偽装を web.config でユーザーに戻すにはどうすればよいですか? または、Web リクエストを作成するときに、偽装コンテキストがそのリクエストにのみ適用されるようにする方法はありますか?

これらすべての要点は、2 番目のアプリケーションが独自の SQL サーバー データベースを持っていることです。プライマリ アプリケーションは DB2 を使用します。一度データベースアクセスコードを書きたいのですが、両方のアプリケーションで使用しています。現在、それは私が行ったことですが、データを取得するために Web 要求に依存する私の方法は、最善の方法ではない可能性があります。

私は、あらゆる考え、コメント、提案、および/または批判を受け入れます。これをどのように処理すればよいですか?

4

1 に答える 1

1

わかりました... Web リクエストを作成したときに IPrincipal コンテキストが変更されたという私の理論は正確であることが証明されたため、この修正は非常に簡単になりました。最良の部分は、Sql Server Entity Framework パーツを複製することなく、この要求を行うために構築した API を使用し続けることができることです。

API ライブラリへの次の呼び出しがあります。

            proxyRequestResultDetails = ProxyApiWrapper.GetProxies(
                adUserInfo.AssociateId,
                context.User);

このコードは、承認フィルター属性によって呼び出されています。メソッドのプロトタイプは次のようになります

public void OnAuthorization(AuthorizationContext filterContext)     

内部的には、この呼び出しは次の呼び出しで GetProxies メソッドを作成します。

        public static StreamReader GetWebRequestStream(
             string url,
             string contentType,
             bool useDefaultCredentials,
             IPrincipal user)
        {

            var impersonationContext = ((WindowsIdentity)user.Identity).Impersonate();            
            var request = WebRequest.Create(url);

            try
            {
                request.ContentType = contentType;
                //request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
                //request.UseDefaultCredentials = useDefaultCredentials;            
                //IWebProxy p = new WebProxy();
                //request.Proxy = p.
                request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
                request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
                var response = (HttpWebResponse)request.GetResponse();
                return new StreamReader(response.GetResponseStream());
            }
            catch (Exception e)
            {
                impersonationContext.Undo();
                throw e;
            }
            finally
            {
                impersonationContext.Undo();
            }

        }

呼び出し元のメソッドが戻ると、ユーザーの ID は、アプリケーションが偽装するために設定されたものではなくなります。修正は非常に簡単です:

            //Track current identity before proxy call
            IPrincipal user = context.User;
            proxyRequestResultDetails = ProxyApiWrapper.GetProxies(
                adUserInfo.AssociateId,
                context.User);

            //Undo any impersonating done in the GetProxies call
            context.User = user;    

2 行のコードで 12 時間の頭痛が解消されました。それはもっと悪いことだったかもしれません。とにかく。響板になってくれてありがとう。アヒルでこの変換を試みましたが、アヒルは混乱しました。

于 2013-02-01T19:32:04.083 に答える