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

是您在RegisterGlobalFilters方法中的App_Start \ FilterConfig中添加过滤器吗? – Aravind

+0

是的!真的不知道发生了什么,这很奇怪!谢谢! – 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中有类似的东西吗?“<错误的StatusCode =‘401’重定向=‘〜首页/ NoPermissions’/>” –

+0

是的,只要我没有登录系统管理员角色,我得到:localhost的页面无法正常工作 本地主机重定向你太多倍。 – ajtatum