2012-12-14 17 views
3

使用[授权]属性可轻松设置仅由特定用户或角色允许的操作。例如。 除了给定的用户/角色,操作是否可以授权每个人?

[Authorize(Roles = "Administrator")] 
public ActionResult Index() 
{ 
    ... 

不过,我遇到了一个问题,当我想要的倒数。有没有一种方法使用MVC框架功能,以允许所有通过身份验证的用户,除了指定的名称或角色?

期望使用将一个类似于:

[DoNotAuthorize(Roles = "RestrictedUser")] 
public ActionResult Index() 
{ 
    ... 

回答

5

一个相当简单的解决方案是从AuthorizeAttribute类派生并覆盖其AuthorizeCore方法,交换其真/假逻辑。

/// <summary> 
/// Authorizes any authenticated user *except* those who match the provided Users or Roles. 
/// </summary> 
public class DoNotAuthorizeAttribute : AuthorizeAttribute 
{ 
    /// <summary> 
    /// This is effectively a copy of the MVC source for AuthorizeCore with true/false logic swapped. 
    /// </summary> 
    /// <param name="httpContext">The HTTP context, which encapsulates all HTTP-specific information about an individual HTTP request.</param> 
    /// <returns>true if the user is authorized; otherwise, false.</returns> 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
     { 
      throw new ArgumentNullException("httpContext"); 
     } 
     IPrincipal user = httpContext.User; 
     if (!user.Identity.IsAuthenticated) 
     { 
      return false; 
     } 

     string[] usersSplit = SplitString(Users); 
     if ((usersSplit.Length > 0) && usersSplit.Contains<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) 
     { 
      return false; 
     } 

     string[] rolesSplit = SplitString(Roles); 
     if ((rolesSplit.Length > 0) && rolesSplit.Any<string>(new Func<string, bool>(user.IsInRole))) 
     { 
      return false; 
     } 

     return true; 
    } 

    /// <summary> 
    /// This is a direct copy of the MVC source for the internal SplitString method. 
    /// </summary> 
    /// <param name="original">The original string to split.</param> 
    /// <returns>An array of strings.</returns> 
    internal static string[] SplitString(string original) 
    { 
     if (string.IsNullOrWhiteSpace(original)) 
     { 
      return new string[0]; 
     } 
     return (from piece in original.Split(new[] { ',' }) 
       let trimmed = piece.Trim() 
       where !string.IsNullOrEmpty(trimmed) 
       select trimmed).ToArray<string>(); 
    } 
} 
2

你可以只列出接受的角色,并留下异常出

[Authorize(Roles = "Administrator, Admin, SuperUser")] 
public ActionResult Index() 
{ 
} 

或建立特殊AuthorizeAttribute与逻辑

+1

列出所有接受的角色,将工作,如果可能的角色列表是有限的。在这种情况下,它们是数据库驱动的,并且需要频繁添加。 – hemp

相关问题