6

我目前正在编写一个 Admin MVC 3 站点,每个用户只能访问该站点的某些部分。

我站点的区域与用户角色相同,所以我想做的是将 AuthorizeAttribute 放在每个区域上,使用区域的名称作为角色中的参数。

到目前为止,当我对每个区域的检查进行硬编码时,我已经完成了这项工作,但我只想遍历所有区域并应用 Authorize 过滤器。(我使用它作为我的自定义 FilterProvider - http://www.dotnetcurry.com/ShowArticle.aspx?ID=578

到目前为止我的代码(“Gcm”是我的领域之一,也是一个角色):

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    // for all controllers, run AdminAuthorizeAttribute to make sure they're at least logged in
    filters.Add(ObjectFactory.GetInstance<AdminAuthorizeAttribute>());

    AdminAuthorizeAttribute gcmAuthroizeAttribute = ObjectFactory.GetInstance<AdminAuthorizeAttribute>();
    gcmAuthroizeAttribute.Roles = "Gcm";

    var provider = new FilterProvider();
    provider.Add(
        x =>
        x.RouteData.DataTokens["area"] != null && x.RouteData.DataTokens["area"].ToString() == "Gcm"
            ? gcmAuthroizeAttribute
            : null);
    FilterProviders.Providers.Add(provider);
}

有谁知道如何获取我的应用程序的所有区域,所以我可以遍历它们,而不是对每个区域进行硬编码?

或者,如果有人对如何按区域进行授权有更好的想法,那将不胜感激。

感谢您的帮助萨恩

4

3 回答 3

2

您可以为每个区域制作一个基本控制器,并将授权属性放在基类上。这样您就可以为每个区域的基本控制器传递区域参数。

于 2011-06-30T22:10:23.253 回答
0

这是我创建的授权属性覆盖的示例。我需要我的授权函数来支持成员船的类型,所以你可能不想太深入函数的内部工作,但 AuthorizeCore 是主要逻辑发生的地方。就我而言,我正在对照实体数据上下文检查它。

用法:

[AjaxAuthorize(AjaxRole = "Administrators")]
public JsonResult SaveAdministrativeUser(v.... )

代码:

 public class AjaxAuthorizeAttribute : AuthorizeAttribute
    {
        private class HttpAuthorizeFailedResult : ActionResult
        {
            public override void ExecuteResult(ControllerContext context)
            {                
                // Set the response code to 403.   Membership.Provider.Name == "UnitArchiveMembershipProvider"
                context.HttpContext.Response.StatusCode = context.HttpContext. User.Identity is WindowsIdentity ?  401 : 403; 
            }
        }

        public string AjaxRole { get; set;}

        public AjaxAuthorizeAttribute()
        {
            AjaxRole = "Users";
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (string.IsNullOrEmpty(MvcApplication.Config.DBSettings.Database))
            {
                return true;
            }

            //When authorize parameter is set to false, not authorization should be performed.
            UnitArchiveData db = DataContextFactory.GetWebRequestScopedDataContext<UnitArchiveData>(MvcApplication.Config.DBSettings.GetConnectionString());            


            if (httpContext.User.Identity.IsAuthenticated)
            {
                login_data user = db.login_datas.Where(n => n.EmailAddress == httpContext.User.Identity.Name).FirstOrDefault();
                if (user != null)
                {
                    return user.cd_login_role.RoleName == "Administrators" || user.cd_login_role.RoleName == AjaxRole;
                }
            }

            return false;

        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                //Ajax request doesn't return to login page, it just returns 403 error.
                filterContext.Result = new HttpAuthorizeFailedResult();
            }
            else
                base.HandleUnauthorizedRequest(filterContext);
        }
    }
于 2011-05-16T14:28:05.450 回答
-1

当我调查一个单独的问题时,我遇到了如何将参数传递给 ASP.NET MVC 2 中的自定义 ActionFilter?

可以更改该属性示例以检查当前控制器的区域。

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        RouteData routeData = filterContext.RouteData;

        // check if user is allowed on this page
        if (SessionFactory.GetSession().Contains(SessionKey.User))
        {
            User user = (User)SessionFactory.GetSession().Get(SessionKey.User);
            string thisArea = routeData.DataTokens["area"].ToString();

            // if the user doesn't have access to this area
            if (!user.IsInRole(thisArea))
            {
                HandleUnauthorizedRequest(filterContext);
            }
        }

        // do normal OnAuthorization checks too
        base.OnAuthorization(filterContext);
    }
}

然后,我将自定义授权属性应用于 Global.asax 中的所有控制器,如下所示:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    // for all controllers, run CustomAuthorizeAttribute to make sure they're at logged in and have access to area
    filters.Add(ObjectFactory.GetInstance<CustomAuthorizeAttribute>());
}

感谢所有回复的人

于 2011-09-14T12:33:57.350 回答