2009-09-04 2 views
6

уставном фильтр позволяет определенной группе пользователей, которые могут получить доступ к контроллеру или действия:ASP.NET MVC: Напротив [Авторизоваться]

[Authorize(Roles="Administrator")] 
public class HomeController : Controller 
{ 
    // code 
} 

Я хотел бы знать, если это возможно, вместо , укажите группу пользователей, что не может получить доступ к контроллеру или действию.

+1

Я не могу представить себе сценарий, при котором переключение от реализации белого списка до реализации черного списка имеет смысл. –

+0

Я не хочу, чтобы мои администраторы обращались к контроллерам, связанным с клиентом, но мне, очевидно, нужны неавторизованные пользователи и клиенты. – ajbeaven

+0

Существует много случаев, когда это имеет смысл, и большинство систем авторизации включают поддержку отказа. Рассмотрим сценарий, когда все пользователи имеют разрешение на выполнение чего-либо, кроме членов определенной роли. – ShadowChaser

ответ

5

Я попытался создать свой собственный AuthorizationAttribute после внушения TWK в:

public class Restrict : AuthorizeAttribute 
{ 
    private readonly string _role; 

    public Restrict(string role) 
    { 
     _role = role; 
    } 

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

     if (httpContext.User.IsInRole(_role)) 
      return false; 

     return true; 
    } 
} 

И я использую это так:

[Restrict("Administrator")] 
public class HomeController : Controller 
{ 
    // code 
} 

Я уверен в том, это правильная практика, но она выполняет эту работу.

+0

выглядит хорошо! :) – jeef3

+0

Ваш атрибут Ограничение принимает сразу несколько роли? – twk

+0

+1 Хорошее простое решение – CmdrTallen

1

Вы должны подготовить свой собственный ActionFilter, который может реализовать такую ​​функцию. По умолчанию существует правило отклонять все, но разрешено определять с помощью фильтра действий авторизации (как вы уже знаете).

вдохновение можно найти there

1

Основано на ajbeaven's answer, мне удалось распространить его на список ролей вместо одной роли.

Во-первых Ограничить класс:

public class Restrict : AuthorizeAttribute { 
    private List<string> _roles; 
    public string Roles { 
     get { 
      string roles = ""; 
      if (_roles != null && _roles.Count > 0) { 
       int counter = 0; 
       foreach (string role in _roles) { 
        counter++; 
        if (counter == _roles.Count) { 
         roles = role; 
        } else { 
         roles += role + ","; 
        } 
       } 
      } 
      return roles; 
     } 
     set { 
      _roles = new List<string>(); 
      string[] roles = value.Split(','); 
      foreach (string role in roles) { 
       _roles.Add(role); 
      } 
     } 
    } 

    public Restrict() { 
     _roles = new List<string>(); 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) { 
     bool result = true; 
     if (httpContext == null) { 
      throw new ArgumentNullException("httpContext"); 
     } 
     foreach (string role in _roles) { 
      if (httpContext.User.IsInRole(role)) { 
       result = false; 
       break; 
      } 
     } 
     return result; 
    } 
} 

Затем добавьте класс AppRoles, чтобы сделать все для повторного использования раствора:

public static class AppRoles { 
    public const string Role1 = "Role1"; 
    public const string Role2 = "Role2"; 
} 

Использование:

[Authorize] 
[Restrict(Roles = AppRoles.Role1 + "," + AppRoles.Role2)] 
    public ActionResult Index() { 
    return View(); 
}