1

Я пробовал создать простой фильтр, чтобы узнать, находится ли пользователь в роли «Системный администратор», в основном короткая рука для выполнения [Authorize(Roles = "System Administrator")]. Я думал, что это будет довольно просто, но я также довольно новичок в MVC, поэтому, возможно, я что-то пропускаю.ASP.Net Identity 2 - Почему мой фильтр не работает?

Вот мой код:

using System.Web.Mvc; 

namespace site_redesign_web.Filters 
{ 
    public class SystemAdminFilter : ActionFilterAttribute 
    { 
     string SysAdminRole = "System Administrator"; 

     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.RequestContext.HttpContext.User != null) 
      { 
       var userSysAdmin = filterContext.RequestContext.HttpContext.User.IsInRole(SysAdminRole) == true; 
       filterContext.ActionParameters["IsSysAdmin"] = userSysAdmin; 
      } 
     } 
    } 
} 

Может кто-нибудь предложить, где я буду неправильно? Огромный плюс будет, если человек не является системным администратором, он направит их на Home/NoPermissions.

Спасибо!

+0

вы можете выставить весь класс вашего фильтра? – Aravind

+0

Обновлен, чтобы показать весь класс. Спасибо! – ajtatum

+0

Это сообщение может быть полезно для понимания лучше https://code.msdn.microsoft.com/ASPNET-MVC-5-Security-And-44cbdb97 – bijayk

ответ

1

Обновлено: Закрепление все вопросы. AJ. Здесь вы идете ... Наконец исправлена ​​проблема

using ActionFilterAttribute 
using System.Web.Mvc; 
namespace site_redesign_web.Filters 
{ 
    public class SystemAdminFilter : ActionFilterAttribute 
    { 
     string SysAdminRole = "System Administrator"; 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (filterContext.RequestContext.HttpContext.User != null) 
      { 
       var userSysAdmin = filterContext.RequestContext.HttpContext.User.IsInRole(SysAdminRole) == true; 

      if(!userSysAdmin) 
      { 
       filterContext.Result = new RedirectToRouteResult(
        new System.Web.Routing.RouteValueDictionary{ 
        {"controller", "Home"},  
        {"action", "Index"} 
       }); 
      } 
      } 
     } 
    } 
} 

и ваш контроллер должен быть

[SystemAdminFilter]  // at controller level 
public SomeController : Controller 
{ 

} 

или вы можете также использовать его для конкретного действий по аннотирования, как этот

public SomeController : Controller 
{ 
    [SystemAdminFilter]  // at Action level 
    public ActionResult SomeAction() 
    { 
      // perform your actions 
    } 

Это будет работать, потому что я вручную передал пользователю пользователя его роль в Application_AuthorizeRequest в Global.asax

protected void Application_AuthorizeRequest(Object sender, EventArgs e) 
{ 
    FormsAuthenticationTicket formsAuthenticationTicket = new FormsAuthenticationTicket("Aravind", true, 30); 
    FormsIdentity formsIdentityId = new FormsIdentity(formsAuthenticationTicket); 
    GenericPrincipal genericPrincipal = new GenericPrincipal(formsIdentityId, new string[] { "SystemUser" }); //TEST with this redirected to Home Index place 
    HttpContext.Current.User = genericPrincipal ; 
} 

Следующий тест я сделал был с этим

GenericPrincipal genericPrincipal = new GenericPrincipal(formsIdentityId, new string[] { "System Administrator" }); //TEST with this did not perform an action 
+0

Когда я попытался реализовать это, я получил: Ошибка HTTP 404.15 - Не найдено Модуль фильтрации запросов настроен на отказ в запросе, где строка запроса слишком длинная. URL-адрес заканчивается длиной более 2k. – ajtatum

+0

- добавление фильтра в App_Start \ FilterConfig в методе RegisterGlobalFilters? – Aravind

+0

yep! На самом деле не знаю, что происходит, это очень странно! Спасибо! – ajtatum

1

Поскольку вы имеете дело с авторизацией, я бы расширил AuthorizeAttribute вместо ActionFilterAttribute, который является режимом общего. Вам необходимо переопределить только один метод - HandleUnauthorizedRequest, который выполняется, когда авторизация завершается с ошибкой. По умолчанию реализация AuthorizeAttribute уже обрабатывает авторизацию на основе ролей.

public class SystemAdminAttribute : AuthorizeAttribute 
{ 
    private const string SysAdminRole = "System Administrator"; 

    public SystemAdminFilter() 
    { 
     //this defines the role that will be used to authorize the user: 
     this.Roles = SysAdminRole; 
    } 

    //if user is not authorized redirect to "Home/NoPermissions" page 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if(!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
     else 
     { 
      filterContext.Result = new RedirectToRouteResult(new 
       RouteValueDictionary(new { controller = "Home", action = "NoPermissions" })); 
     } 
    }   
} 

После того, как ваш атрибут реализован, украшают соответствующие контроллеры или действия с ним:

[SystemAdmin] 
public SysAdminController : Controller 
{ 
} 
+0

Выглядит хорошо, но когда я его реализовал, он выдает анонимных пользователей на страницу NoPermissions. Он работает только при входе в систему с правами системного администратора. – ajtatum

+0

Это очень странно, потому что, когда пользователь не аутентифицирован (это условие истинно: '! FilterContext.HttpContext.User.Identity.IsAuthenticated'), выполняется следующая строка:' base.HandleUnauthorizedRequest (filterContext); 'который должен перенаправляться на логин стр. У вас есть что-то подобное в вашем web.config?'' –

+0

Да, как только я вхожу в систему без роли системного администратора, я получаю: страница localhost не работает localhost перенаправил вас слишком много раз. – ajtatum