Улучшение производительности и расширяемости моего пользовательского модуля авторизации

У меня есть требование авторизации, чтобы мои роли безопасности основывались на методах действий, чего нельзя достичь с помощью авторизации asp.net mvc по умолчанию. поэтому я создал следующий фильтр действий для реализации моих пользовательских требований авторизации: -

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {
        Repository repository = new Repository();
        public string Model { get; set; }
        public string Action { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
           // var user = User.Identity.Name; // or get from DB 
            string ADusername = filterContext.HttpContext.User.Identity.Name.Substring(filterContext.HttpContext.User.Identity.Name.IndexOf("\\") + 1);
            if (!repository.can(ADusername,Model,Action)) // implement this method based on your tables and logic
            {
                filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");

            }

            base.OnActionExecuting(filterContext);
        }
    }

который вызывает следующий метод репозитория: -

public bool can(string user, string Model, string Action)
        {
            bool result;
            bool result2;


int size = tms.PermisionLevels.Where(a5 => a5.Name == Action).SingleOrDefault().PermisionSize;
var securityrole = tms.SecurityroleTypePermisions.Where(a => a.PermisionLevel.PermisionSize >= size && a.TechnologyType.Name == Model).Select(a => a.SecurityRole).Include(w=>w.Groups).Include(w2=>w2.SecurityRoleUsers).ToList();//.Any(a=> a.SecurityRoleUsers.Where(a2=>a2.UserName.ToLower() == user.ToLower()));

foreach (var item in securityrole)
                    {
result = item.SecurityRoleUsers.Any(a => a.UserName.ToLower() == user.ToLower());
var no = item.Groups.Select(a=>a.TMSUserGroups.Where(a2=>a2.UserName.ToLower() == user.ToLower()));
result2 = no.Count() == 1;
if (result || result2) 
{
    return true;
}}
return false;

я вызываю фильтр действий внутри моего класса контроллера следующим образом: -

   [CheckUserPermissions(Action = "Read", Model = "Server")]

но у меня есть следующие опасения: -

  1. внутри моего репозитория я буду извлекать всех пользователей и группы (при вызове .Tolist()), а затем проверять, находится ли текущий пользователь входа в эти значения. который не будет очень расширяемым при работе с огромным количеством пользователей?

  2. каждый раз, когда пользователь вызывает метод действия, будет запускаться один и тот же код безопасности (конечно, в идеале разрешение пользователя может измениться во время сеанса пользователя), что может вызвать проблемы с производительностью?

Так может ли кто-нибудь посоветовать, как я могу улучшить свою текущую реализацию, принимая во внимание две проблемы? Спасибо




Ответы (1)


Я бы изменил ваш подход и использовал аутентификацию на основе утверждений.

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

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

В этой статье объясняется, как реализовать это, а также использовать безопасные билеты сеанса, чтобы каждый раз не обращаться к базе данных.

http://dotnetcodr.com/2013/02/25/claims-based-authentication-in-mvc4-with-net4-5-c-part-1-claims-transformation/

person hutchonoid    schedule 29.10.2013
comment
если честно, мне потребуется много времени, чтобы изменить мой текущий подход, так как я раньше не работал над авторизацией претензий. я знаю, что мой текущий подход не самый лучший, но я пытаюсь улучшить его, насколько это возможно. спасибо - person john Gu; 29.10.2013
comment
Нет проблем, стоит прочитать эту статью, когда у вас будет время. Удачи. - person hutchonoid; 29.10.2013
comment
извините, я забыл включить код класса репозитория. я обновил свой оригинальный пост. - person john Gu; 29.10.2013