0

私は MVC を初めて使用し、ステージング Web サーバーでアプリケーションを実行するのに苦労しています。私のローカル マシンと開発サーバーでは問題なく動作しています。

問題は、私のアクションではユーザーがnullであることです(ステージングではなく、開発およびローカルではありません)。User が null になる理由をグーグルで検索しましたが、すべてがカバーされているようです。奇妙なことは、2 つのサーバーで完全に動作することです。

これが私のコードです...

Global.asax で PostAcquireRequestState を使用して、Session に格納されたオブジェクトを保持するカスタム プリンシパルを使用してプリンシパルをオーバーライドします。したがって、オブジェクトを取得してプリンシパルに追加する SessionHelper です。次に、プリンシパルが httpcontext とスレッドに設定されます。

public class MvcApplication : HttpApplication
{
    public MvcApplication()
    {
        PostAcquireRequestState += new EventHandler(MvcApplication_PostAcquireRequestState);
    }

    void MvcApplication_PostAcquireRequestState(object sender, EventArgs e)
    {
        if (Context.User is ICSPrincipal)
            return;

        var principal = new ICSPrincipal(new GenericIdentity(User.Identity.Name), SessionHelper.UserClaims);
        HttpContext.Current.User = principal;
        Thread.CurrentPrincipal = principal;
    }

    ...
}

私のコントローラーでは、プリンシパルに格納されている値を取得します。しかし、問題は、ステージング サーバーで User が null であることです。ただし、ローカル マシンと開発サーバーでは動作します。開発サーバーとステージング サーバーは同じバージョンの IIS を実行しており、どちらにも MVC3 がインストールされています。

public class HomeController : Controller
{
   public ActionResult Index()
   {
        //PROBLEM!!! User is NULL on staging server.
        var userClaims = ((ICSPrincipal)User).UserClaims;
        ...
   }
}

この問題の経験があり、解決した人はいますか? アクション内から User を安全に呼び出すことができるという印象を受けました。

編集:カスタムプリンシパルと組み合わせてSessionStorageが必要な理由に関する状況スケッチ。

認証がカバーされるように、フォーム認証を使用します。ただし、追加のユーザーデータ (名、姓、合計 6 つのプロパティ) を保持するオブジェクトを認証 Cookie のユーザーデータに格納していました。ただし、リクエストを調査したところ、各リクエスト (画像の場合でも。Cookie を使用しないドメインを使用してこれを最適化できることはわかっていますが、それは次のステップです) が 2.5KB を超えていることがわかりました。そのため、ユーザー名をCookieに保存するだけに戻し、リクエストごとにセッションストレージからデータを完成させたいと考えています。そのため、カスタム プリンシパルが優れていると考えました。それは一般的なプリンシパルから始まり、アクションに到達すると、必要なすべてのデータが必要な場所から取得されたカスタム プリンシパルがあります (この場合、セッションからのデータが追加された Cookie からのユーザー名)。

私はあなたが言うのを聞きます: しかしねえ、Session の使用は安全ではありません。しばらくすると有効期限が切れます。そして、私はこれをよく知っています。それが、SessionHelper がある程度の知性を持っている理由です。Session オブジェクトが null の場合、認証されたユーザーのユーザー名に基づいて、必要なすべてのデータが取得されます。このデータをセッションに保存して、後続のリクエストがデータベースにクエリを実行しないようにします。

API 通信 (http または名前付きパイプ) も使用しているため、カスタム プリンシパルでこのデータが必要です。そのレイヤーからセッションにアクセスすることはできませんが、プリンシパルにはアクセスできます。したがって、その通信に到達する前にプリンシパルが更新された場合、すべてが正常に機能します。

実際の問題への取り組み:

上記の設定は実際には複数のマシンで正常に動作しますが、私の開発サーバーと同じ設定であるステージング サーバーでは機能しません。私のアクションで User が null であるというステージングの苦情。そして、それがどのように可能かさえわかりません。

4

2 に答える 2

2

PostAcquireRequestState は、これを行うには奇妙な場所です。AuthenticateRequest でそれを行う必要があります。また、HttpContext.Current.User ではなく Context.User を設定する必要があります。

于 2012-04-12T18:38:24.323 に答える
0

http://support.microsoft.com/kb/980368/en

このパッチを適用すると、ASP.NET 4 アプリケーションは拡張子のない URL の要求を処理できるようになります。したがって、ハンドラーの実行前に実行されるマネージ HttpModules が実行されます。場合によっては、HttpModules が拡張子のない URL に対してエラーを返すことがあります。たとえば、.aspx 要求のみを想定して作成された HttpModule は、HttpContext.Session プロパティにアクセスしようとするとエラーを返す場合があります。

これで問題は解決しました!複数の設定を試していただきありがとうございます。このようにして、私はこの解決策を思いつきました。

于 2012-04-13T16:11:19.107 に答える