web-dev-qa-db-ja.com

MVC4でAuthorizeAttributeをオーバーライドする

私のアプリケーションでは、許可されたユーザーが必要な情報を提供するまで、プロファイルページを更新するようにリダイレクトしたいと思います。プロファイルを更新すると、データベースでIsProfileCompletedが「true」に設定されます。

ですから、コントローラーの必要なアクションにチェック条件を入れることでこれができることを私は知っています。しかし、私はAuthorizeAttributeをカスタマイズすることによってこれを行いたいと思います。

私はグーグルで「StackOverflowed」と情報を求めましたが、混乱しました。案内してください。

16
Mukesh Sharma
public class MyAuthorizeAttribute: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            // The user is not authorized => no need to go any further
            return false;
        }

        // We have an authenticated user, let's get his username
        string authenticatedUser = httpContext.User.Identity.Name;

        // and check if he has completed his profile
        if (!this.IsProfileCompleted(authenticatedUser))
        {
            // we store some key into the current HttpContext so that 
            // the HandleUnauthorizedRequest method would know whether it
            // should redirect to the Login or CompleteProfile page
            httpContext.Items["redirectToCompleteProfile"] = true;
            return false;
        }

        return true;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Items.Contains("redirectToCompleteProfile"))
        {
            var routeValues = new RouteValueDictionary(new
            {
                controller = "someController",
                action = "someAction",
            });
            filterContext.Result = new RedirectToRouteResult(routeValues);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }

    private bool IsProfileCompleted(string user)
    {
        // You know what to do here => go hit your database to verify if the
        // current user has already completed his profile by checking
        // the corresponding field
        throw new NotImplementedException();
    }
}

次に、このカスタム属性を使用してコントローラーアクションを装飾できます。

[MyAuthorize]
public ActionResult FooBar()
{
    ...
}
39
Darin Dimitrov

このコードを使用して、独自の変更をいくつか追加しました。つまり、現在ログインしているユーザーがサーバー上でセッション状態にあるかどうかを確認するために、以前ほど高価ではありません。

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized && !Membership.isAuthenticated())
        {
            // The user is not authorized => no need to go any further
            return false;
        }

        return true;
    }
}
public class Membership
{
    public static SystemUserDTO GetCurrentUser()
    {
        // create a system user instance
        SystemUserDTO user = null;

        try
        {
            user = (SystemUserDTO)HttpContext.Current.Session["CurrentUser"];
        }
        catch (Exception ex)
        {
            // stores message into an event log
            Utilities.Log(ex.Message, System.Diagnostics.EventLogEntryType.Warning);

        }
        return user;
    }

    public static bool isAuthenticated()
    {
        bool loggedIn = HttpContext.Current.User.Identity.IsAuthenticated;
        bool hasSession = (GetCurrentUser() != null);
        return (loggedIn && hasSession);
    }
}
0
Terry Kernan