asp.net MVC 3 применяя AuthorizeAttribute к областям - PullRequest
6 голосов
/ 16 мая 2011

В настоящее время я пишу сайт Admin MVC 3, и каждый пользователь имеет доступ только к определенным частям сайта.

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

Пока у меня это работает, когда я жестко кодирую проверку каждой области, но я хотел бы просто пройтись по всем областям и применить фильтр авторизации. (Я использую это как мой собственный 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);
}

Кто-нибудь знает, как получить все области моего приложения, чтобы я мог просто проходить через них, а не жестко кодировать каждую область?

Или, если у кого-то есть лучшее представление о том, как авторизоваться в каждой области, это будет оценено.

Спасибо за вашу помощь Saan

Ответы [ 3 ]

2 голосов
/ 01 июля 2011

Вы можете создать базовый контроллер для каждой области и поместить атрибут авторизации над базовым классом. Таким образом, вы можете передать параметр области для каждого базового контроллера области.

0 голосов
/ 14 сентября 2011

Когда я изучал отдельную проблему, я столкнулся с Как передать параметры в пользовательский ActionFilter в ASP.NET MVC 2?

Этот пример атрибута может быть изменен для проверки текущей области контроллера.

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>());
}

Спасибо всем, кто ответил

Saan

0 голосов
/ 16 мая 2011

Вот пример созданного мной переопределения атрибута Authorize. Мне нужна была моя функция авторизации для поддержки типов членов, так что вы, возможно, не захотите слишком углубляться во внутреннюю работу функций, но в 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);
        }
    }
...