如何在不使用角色时将[授权]重定向到loginUrl?

时间:2010-03-24 02:11:17

标签: asp.net-mvc

我希望[Authorize]重定向到 loginUrl ,除非我还使用了某个角色,例如[Authorize (Roles="Admin")]。在这种情况下,我只想显示一个页面,说明用户未获得授权。

我该怎么办?

3 个答案:

答案 0 :(得分:25)

以下是我修改后的AuthorizeAttribute实施的代码;我把它命名为SecurityAttribute。我唯一改变的是OnAuthorization方法,我为Url添加了一个额外的字符串属性,以重定向到Unauthorized页面:

// 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);
    }
}

您以与原始AuthorizeAttribute相同的方式调用它,除了有一个额外的属性来覆盖未授权的网页网址:

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

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

答案 1 :(得分:15)

扩展AuthorizeAttribute课程并覆盖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);
    }
}

用法

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

}

并确保在配置

中添加AppSettings条目
<appSettings>
  <add key="RolesAuthRedirectUrl" value="http://mysite/myauthorizedpage" />
</appSettings>

答案 2 :(得分:2)

我发现最简单的方法是扩展和自定义AuthorizeAttribute,以便在角色检查失败时执行不同的操作(即,不设置HttpUnauthorizedResult)。我在我的博客上写了一篇article,你可能觉得它很有用。这篇文章描述了你想要的东西,尽管它更进一步,并允许“拥有”数据的用户也可以访问该操作。我认为根据您的目的进行修改应该相当容易 - 您只需删除“或所有者”部分。