4

ASP.NETMVC4Webアプリのカスタムプリンシパル/IDがあります。また、カスタムプリンシパルをインスタンス化するためのAuthorizeAttributeを作成し、認証が必要なコントローラーのhttpContext.Userに割り当てました。

これは、AuthorizeAttributeで装飾されたコントローラー/アクションには最適ですが、認証を必要としない(ただし、認証が存在する場合は引き続き使用する)コントローラーの場合は、CustomPrincipalを取得したいと思います(できればHttpContext.Userを使用します)。 )

これらの装飾されていないコントローラー/アクションでは、HttpContext.Userが設定されていますが、CustomPrincipalではなくGenericPrincipalが設定されています。HttpContext.Userのデフォルト設定をGenericPrincipalに「オーバーライド」するのに最適な場所はどこですか?

同様に、これが認証Cookieを持つすべてのリクエストで行われる場合、AuthorizeAttributeで装飾されたコントローラー(認証を義務付けるコントローラーになる)の場合、2回の作業を回避するにはどうすればよいでしょうか。

明確にするために、私のサイトでは匿名ユーザーによるアクセスが許可されていますが、これらのページで認証された場合(およびCustomPrincipalが実現された場合)、追加の機能が提供されます。

いくつかのオプションは次のとおりだと思います(それぞれの背後にある私のロジックは確かではありません):

  • セッションを使用します(そして、プリンシパルを忘れて、ここで必要なものを作成するためのロジックを処理します)
  • Application_AuthenticateRequest-これは古い学校であるというウェブ上のコメントを見た
  • ベースコントローラーに設定されたカスタムフィルター
  • ベースコントローラー上にAuthorizationAttributeを作成します。これにより、全員がHttpContext.Userを通過し、必要に応じて設定できます。
  • IHttpModule-これは下降的な方法のようです(他の人が同意しない限り、この道を進んでください)。

考え?

4

2 に答える 2

19

グローバルアクションフィルターを使用できます。カスタムプリンシパルがあるとしましょう。

public class MyPrincipal : GenericPrincipal
{
    public MyPrincipal(IIdentity identity, string[] roles): base(identity, roles)
    {
    }

    ... some custom properties and stuff
}

次に、グローバル認証アクションフィルターを作成できます(ただし、グローバル認証を回避するためにベースから派生するのではなく、他のフィルターの前に実行されるようにインターフェイスをAuthorizeAttribute実装するだけです)。IAuthorizationFilter

public class GlobalIdentityInjector : ActionFilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var identity = filterContext.HttpContext.User.Identity;

        // do some stuff here and assign a custom principal:
        var principal = new MyPrincipal(identity, null);
        // here you can assign some custom property that every user 
        // (even the non-authenticated have)

        // set the custom principal
        filterContext.HttpContext.User = principal;
    }
}

グローバルフィルターはに登録される~/App_Start/FilterConfig.csため、すべてのアクションに適用されることが保証されます。

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new GlobalIdentityInjector());
    }
}

そして今、あなたは認証を必要とする特定のコントローラーアクションにのみ適用されるカスタム認証属性を持つことができます:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        // we know that at this stage we have our custom
        // principal injected by the global action filter
        var myPrincipal = (MyPrincipal)httpContext.User;

        // do some additional work here to enrich this custom principal
        // by setting some other properties that apply only to
        // authenticated users

        return true;

    }
}

次に、2種類のアクションを実行できます。

public ActionResult Foo()
{
    var user = (MyPrincipal)User;

    // work with the custom properties that apply only
    // to anonymous users

    ...
}

[MyAuthorize]
public ActionResult Bar()
{
    var user = (MyPrincipal)User;

    // here you can work with all the properties
    // because we know that the custom authorization
    // attribute set them and the global filter set the other properties

    ...
}
于 2012-07-14T10:21:47.700 に答える
0

プリンシパルのオーバーライド:

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)

それ以外の

protected void Application_AuthenticateRequest(object sender, EventArgs e)

Global.asax.csでは、ASPWebアプリケーションで動作しました

于 2013-10-22T14:46:03.297 に答える