2

シナリオ

WindowsAzureでホストされるMVCアプリケーションを開発します。開発中、ローカルデータベースとローカルユーザーメンバーシップサービスに対してテストします。本番環境では、アプリケーションはSQLAzureデータベースとクラウドでホストされるユーザーメンバーシップサービスを利用します。

ローカルマシンにのみ存在するユーザーアカウントを使用して、サイトのローカルバージョンにログインすることがあります。ログアウトするのを忘れたが、マシンをテストモードから切り替えると、問題が発生し始めます。

問題

ブラウザーの要求がAzureエミュレーターによってローカルで処理されるようにhosts、アプリケーションのURLを指すようにファイルを設定しました。127.255.0.0これは、テストアプリケーションと本番アプリケーションが同じホスト名を使用していることも意味します。一方のCookieは、もう一方の有効なCookieと見なされます。

ローカルシステムにログインするとASPXAUTH、ドメインのCookieが作成され、ローカルシステムのユーザーの資格情報が含まれます。ログアウトしてhostsファイルを通常の状態に戻すのを忘れた場合(ブラウザーの要求はライブアプリケーションに送信されます)、ASPXAUTHサーバーに同じCookieが送信されます。

このユーザーはサーバー上に存在せず、ローカルにのみ存在するため、などのリクエストMembership.GetUser().Emailはオブジェクトnull例外を返します。

やりたいこと

理想的には、リクエストの早い段階でコードを挿入して、ユーザーが存在することを確認できます。何かのようなもの:

MembershipUser user = Membership.GetUser();
if(user == null) {
    FormsAuthentication.SignOut();
}

ASPXAUTHこれにより、無効なユーザーのCookieが自動的に削除されます。しかし、どこに置くのですか?私は自分のコントローラーを見始めました-それらはすべてBaseControllerクラスから継承しますが、このコードをベースコントローラーのコンストラクターに入れることさえ十分に早い段階ではありません。も調べましたGlobal.asaxが、このアクションをどのイベントに結び付けるのが最適かわかりません。

また、これが正しい方法かどうかさえわかりません。そうでない場合、現在のようにメンバーシップクラスに依存する前に、認証Cookieが有効なユーザー用であることを確認するための最良の方法は何ですか?

4

2 に答える 2

4

global.aspxで以下のイベントを処理できます。

public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{ 
}

編集:

上記のメソッドでは、プロパティからuserNameを取得し、この場合、ユーザーはまだ認証されていないため、Membership.GetUser()を返します。上記のメソッドは、Authenticateを発生させたときにFormsAuthenticationModuleによって呼び出されます。このイベントは次のように処理できます。nullHttpContext.Current.User.Identity.Name

public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
{
    if (FormsAuthentication.CookiesSupported &&
            Request.Cookies[FormsAuthentication.FormsCookieName] != null)
    {
        try
        {
            var formsAuthTicket = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value);

            MembershipUser user = Membership.GetUser(formsAuthTicket.Name);
            if (user == null)
            {
                FormsAuthentication.SignOut();
                Request.Cookies[FormsAuthentication.FormsCookieName].Value = null;
            }
        }
        catch (Exception ex)
        {
            //TODO:log ex
        }
    }
}

global.aspxで以下のメソッドを宣言することにより、 AuthenticateRequestイベントの処理を検討することもできます。

注:Application_AuthenticateRequestイベントは、FormsAuthentication_OnAuthenticateイベントの後に発生します。

void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)
    {                
        MembershipUser user = Membership.GetUser();
        if (user == null)
        {
            FormsAuthentication.SignOut();
            HttpContext.Current.User = null;
        }
    }            
}

お役に立てれば..

于 2012-05-02T19:19:26.617 に答える
0

をオーバーライドするベースコントローラーを作成し、OnActionExecutingそこにコードを配置します。すべてのコントローラーコントローラーに彼から継承させます。これは OnActionExecuting私が持っていた古いプロジェクトからのものです

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    if (Request.IsAuthenticated)
    {
        if (Session[SomeKey] == null)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Account" }, { "action", "LogOff" } });
        }
    }
    base.OnActionExecuting(filterContext);
}

基本的に、リクエストが認証されているかどうかを確認しています。認証されていない場合は、ログアウトアクションにリダイレクトします。 http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.onactionexecuting.aspx

于 2012-05-02T22:32:51.460 に答える