覆盖MVC 4中的AuthorizeAttribute

Muk*_*rma 16 asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

在我的应用程序中,我想重定向授权用户更新他们的个人资料页面,直到他们提供了所需的信息.如果他们更新配置文件,则IsProfileCompleted在数据库中将其设置为"true".

所以,我知道这可以通过将检查条件放在控制器的所需操作中来完成.但我想通过自定义来做到这一点AuthorizeAttribute.

我用谷歌搜索和'StackOverflowed'获取信息,但感到困惑.请指导我.

Dar*_*rov 39

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以用这个自定义属性装饰你的控制器动作:

[MyAuthorize]
public ActionResult FooBar()
{
    ...
}
Run Code Online (Sandbox Code Playgroud)