How to use authorize attribute on MVC3

2019-01-23 18:16发布

问题:

I've read that to use the attribute [Authorize] on MVC, you just have to place it over an action or over the controller class you want to secure.

My question is: How does the Authorize attribute know if a user is logged or not? Do i have to provide any Session object in order to let Authorize know if a user is authorized?

回答1:

This attribute works by looking at HttpContext.User.Identity.IsAuthenticated.

If you're using something like FormsAuthentication, this will be set to true if the user has a valid FormsAuthentication cookie on their machine (which you can add by using FormsAuthentication.SetAuthCookie).

If you're interested in the inner-workings of Authorize, this is from the published Microsoft source code:

protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
        if (httpContext == null) {
            throw new ArgumentNullException("httpContext");
        } 

        IPrincipal user = httpContext.User; 
        if (!user.Identity.IsAuthenticated) { 
            return false;
        } 

        if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) {
            return false;
        } 

        if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) { 
            return false; 
        }

        return true;
    }

Here is some more info on FormsAuthentication.



回答2:

Authorize attribute class by default takes the httpcontext as argument. when called. It then checks the HttpContext.User.Identity.IsAuthenticated bool value and acts accordingly. This works only if you use Forms authentication. If you are using your own login logic (in session object for example), you can derive a class from Authorize Attribute and call it.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true,     AllowMultiple = true)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        clsSession sess = httpContext.Session["Current"] as clsSession;
        if (sess.IsLogin) return true;
        return false;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new ViewResult { ViewName = "Unauthorized" };
    }
}

Then you can use this class like this:

[MyAuthorize]
public ActionResult Index()
{
    return View();
}

This will work. You can use [MyAuthorize] instead of [Authorize] in all controller actions. If it returns false, it will return a view (In this case "Unauthorized"). The view name could be anything and can be located in the views/shared folder.