开发者

How to redirect [Authorize] to loginUrl only when Roles are not used?

I'd like 开发者_StackOverflow中文版[Authorize] to redirect to loginUrl unless I'm also using a role, such as [Authorize (Roles="Admin")]. In that case, I want to simply display a page saying the user isn't authorized.

What should I do?


Here is the code from my modified implementation of AuthorizeAttribute; I named it SecurityAttribute. The only thing that I have changed is the OnAuthorization method, and I added an additional string property for the Url to redirect to an Unauthorized page:

// Set default Unauthorized Page Url here
private string _notifyUrl = "/Error/Unauthorized"; 

public string NotifyUrl { 
    get { return _notifyUrl; } set { _notifyUrl = value; } 
}

public override void OnAuthorization(AuthorizationContext filterContext) {
    if (filterContext == null) {
        throw new ArgumentNullException("filterContext");
    }

    if (AuthorizeCore(filterContext.HttpContext)) {
        HttpCachePolicyBase cachePolicy =
            filterContext.HttpContext.Response.Cache;
        cachePolicy.SetProxyMaxAge(new TimeSpan(0));
        cachePolicy.AddValidationCallback(CacheValidateHandler, null);
    }

    /// This code added to support custom Unauthorized pages.
    else if (filterContext.HttpContext.User.Identity.IsAuthenticated)
    {
        if (NotifyUrl != null)
            filterContext.Result = new RedirectResult(NotifyUrl);
        else
           // Redirect to Login page.
            HandleUnauthorizedRequest(filterContext);
    }
    /// End of additional code
    else
    {
         // Redirect to Login page.
        HandleUnauthorizedRequest(filterContext);
    }
}

You call it the same way as the original AuthorizeAttribute, except that there is an additional property to override the Unauthorized Page Url:

// Use custom Unauthorized page:
[Security (Roles="Admin, User", NotifyUrl="/UnauthorizedPage")]

// Use default Unauthorized page:
[Security (Roles="Admin, User")]


Extend the AuthorizeAttribute class and override HandleUnauthorizedRequest

public class RoleAuthorizeAttribute : AuthorizeAttribute
{
    private string redirectUrl = "";
    public RoleAuthorizeAttribute() : base()
    {
    }

    public RoleAuthorizeAttribute(string redirectUrl) : base()
    {
        this.redirectUrl = redirectUrl;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            string authUrl = this.redirectUrl; //passed from attribute

            //if null, get it from config
            if (String.IsNullOrEmpty(authUrl))
                authUrl = System.Web.Configuration.WebConfigurationManager.AppSettings["RolesAuthRedirectUrl"];

            if (!String.IsNullOrEmpty(authUrl))
                filterContext.HttpContext.Response.Redirect(authUrl);
        }

        //else do normal process
        base.HandleUnauthorizedRequest(filterContext);
    }
}

Usage

[RoleAuthorize(Roles = "Admin, Editor")]
public class AccountController : Controller
{

}

And make sure you add your AppSettings entry in the config

<appSettings>
  <add key="RolesAuthRedirectUrl" value="http://mysite/myauthorizedpage" />
</appSettings>


The easiest way I've found is to extend and customize the AuthorizeAttribute so that it does something different (i.e., not set an HttpUnauthorizedResult) when the Role check fails. I've written an article about this on my blog that you might find useful. The article describes much what you are wanting, though it goes further and allows the user who "owns" the data to also have access to the action. I think it should be fairly easy to modify for your purposes -- you'd just need to remove the "or owner" part.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜