4

私はMVC3で簡単なことをやろうとしています。

フォーム認証を使用してサードパーティのSSOでユーザーを認証するアプリケーションがあります。SSOは、ログインに成功すると、アプリケーションの特定のコントローラーアクションにポストバックします。次に、を呼び出しますFormsAuthentication.SetAuthCookie(user,false);

あるレベルの認証を実装しようとしています。Admin簡単に言うと、ユーザーは、やなど、さまざまな役割で存在できますDeveloper。一部のコントローラーアクションは、特定の役割でのみ使用可能である必要があります。ユーザーが属するロールの詳細は、別の外部APIを呼び出すことで取得されます。これにより、単純なJSON応答が返されます。

理論的には、これは、FormsAuthenticationCookieを設定した後に次のようなことを行うのと同じくらい簡単なはずです。

string[] rolelist = GetRoleListForUserFromAPI(User.Identity.Name);
HttpContext.User = new GenericPrincipal(User.Identity, rolelist);

ただし、現時点では意味がないSetAuthCookieため、を呼び出した直後にこれを呼び出すことはできません。HttpContext.User

すべてのリクエストでこれを設定してみることができますが、アプリへのリクエストはラウンドトリップAPI呼び出しを意味します。

これまで見てきた中で最も有望なアプローチは、カスタムのAuthorization属性を作成し、オーバーライドOnAuthorizationして次のようなことを行うことです。

public override void OnAuthorization(AuthorizationContext filterContext)
{
    if (<some way of checking if roles have already been set for this user, or role cache has timed out>)
    {
        string[] rolelist = GetRoleListForUserFromAPI(filterContext.HttpContext.User.Identity.Name);
        filterContext.HttpContext.User = new GenericPrincipal(filterContext.HttpContext.User.Identity,rolelist);
    }
}

次に、コントローラーアクションの前で使用[MyCustomAuthorization(Roles="Admin")]して、魔法を起こさせることができます。

HttpContext.Userただし、現在のオブジェクトにロールが設定されているかどうか、または特定の時間前に設定されており、別のAPIトリップが必要かどうかを検出する方法がわかりません。

このための最良のアプローチは何ですか?

4

4 に答える 4

2

オーバーライドする必要がありますPostAuthenticateRequest

protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e) 
{
    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        string[] rolelist = GetRoleListForUserFromAPI(User.Identity.Name);
        HttpContext.User = new GenericPrincipal(User.Identity, rolelist);
    }
}

フォーム認証の処理が終了した後に呼び出されます。

http://msdn.microsoft.com/en-us/library/ff647070.aspx

アップデート

メソッドの署名が間違っていました (自分のアプリケーションの 1 つをチェックインしたところです)。

于 2012-06-08T12:48:25.053 に答える
2

もう 1 つの方法は、FormsAuthentcationTicket の UserData プロパティにロールを格納することです。これは、カンマ区切りの文字列で行うことができます。

http://msdn.microsoft.com/en-us/library/system.web.security.formsauthenticationticket.formsauthenticationticket

その後、AuthenticateRequest メソッドでチケットを取得し、ロール データを取得して、汎用プリンシパルを使用して現在のユーザーに割り当てることができます。

于 2012-06-08T12:56:28.730 に答える
1

私が最初に考えたのは、カスタム ロール プロバイダーの実装を調査する必要があるということです。これはやり過ぎかもしれませんが、役割ベースの配管には合っているようです。

MSDN hereからの詳細情報。

于 2012-06-08T15:11:55.377 に答える
1

一部の人々を驚かせたのは、セッション オブジェクトはここでは悪い考えであるということです。一時データを使用する場合、セッションのヒットはすでに発生しています。

このデータを Cookie に保存します。フォーム認証トークンは、1 年半前から POET の脆弱性ですでに悪用されています。その脆弱性。

@jgauffinが言及したように、これはポスト認証で行うことができます。そこでセッション状態が利用できない場合は、それを Application_PreRequestHandlerExecute で使用して、そこで確認できます。

セッション状態がどちらかで利用可能かどうかを確認したい場合は、次のコードを参照してください: How can I handle forms authentication timeout exceptions in ASP.NET?

また、フォーム認証とセッションを使用するときは常に、タイムアウトが互いに同期していることを常に確認する必要があります (上記のコードでも同様です)。

于 2012-06-08T18:38:34.053 に答える