asp.net mvc, несколько провайдеров ролей CustomAuthorize

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

Я создал класс CustomAuthorize, который содержит метод:

 public class CustomAuthorize : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            Debug.WriteLine("Show me the filterContext " + filterContext);
            if (filterContext.Result is HttpUnauthorizedResult)
            {
                Debug.WriteLine("Why is this going to the redirect to AccessDenied?");
                filterContext.Result = new RedirectResult("~/AccessDenied/Index");
            }
        }
    }

Мой класс RoleProvider:

namespace Office.WebUI.Security {
    public class OfficeRoleProvider : RoleProvider
    {

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            throw new NotImplementedException();
        }

        public override string[] GetRolesForUser(string username)
        {
            Debug.WriteLine("Get the username" + username);
            using (EFDbContext db = new EFDbContext()) >           
            {
                User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, >stringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));
                //User user = db.TaskPrivilege.FirstOrDefault(u => >u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));

                if (user != null)
                {
                    var roles = from ur in user.UserRoles
                                from r in db.Roles
                                where user.role.RoleID == r.RoleID
                                //where ur.RoleID == r.RoleID
                                select r.Name;
                    if (roles != null)
                        return roles.ToArray();
                    else
                        return new string[] { }; ;
                }
                else
                {
                    return new string[] { }; ;
                }
            }
        }

        public override string[] GetUsersInRole(string roleName)
        {
           throw new NotImplementedException();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            Debug.WriteLine("The username is " + username + " And the Role it is using is >" + roleName);
            using (EFDbContext db = new EFDbContext())
            {
                User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));

                if (user != null)
                {
                    var roles = from ur in user.UserRoles
                                from r in db.Roles
                                where user.role.RoleID == r.RoleID
                                //where ur.RoleID == r.RoleID
                                select r.Name;
                    if (user != null)
                        return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));
                    else
                        return false;
                }
                else
                {
                    return false;
                }
            }
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            throw new NotImplementedException();
        }
    }

}

В моей базе данных у меня есть таблица ролей, в которой в качестве столбцов содержатся Role и RoleID, с двумя значениями "Администратор" и "Пользователь" в качестве ролей с ролью ID в качестве PK, 1 = "Администратор" и 2 = "Пользователь". Другая таблица с именем Users, которая содержит UserID, Username и role_RoleID

Когда я назначаю пользователя для role_RoleID как 1 (администратор) и блокирую контроллер, используя

[CustomAuthorize(Roles = "Администратор"]

Это работает.

Когда я назначаю role_RoldID = 2 и блокируюсь, используя:

[CustomAuthorize(Roles = "Пользователь"]

Это не работает?

Еще один вопрос: как мне назначить 2 роли контроллеру? Затем я хочу заблокировать каждый метод для 1 роли пользователя.

Надеюсь, что это имеет смысл, и я надеюсь, что кто-то может мне помочь, пожалуйста.

Спасибо

Стивен

В основном у меня есть контроллер, который я поставил [CustomAuthorize(Roles = "Administrators, Support")] чтобы заблокировать его, чтобы обе роли могли видеть контроллер.

Затем у меня есть методы создания / удаления и редактирования:

[CustomAuthorize(Roles = "Administrators")]

так что в основном я хочу показать весь контроллер обеим ролям, но только администраторы могут создавать / редактировать / удалять.

Когда я назначаю roleID в таблице user = 2(User), все приложение разрывается для этого пользователя. Назначение RoldID = 1 (администраторы) работает для всех людей, которым назначен roldID 1.

В настоящее время у меня есть методы

public override string[] GetRolesForUser(string username)
{

    using (EFDbContext db = new EFDbContext())  

    {
        User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase) || u.Email.Equals(username, StringComparison.CurrentCultureIgnoreCase));


        if (user != null)
        {
            var roles = from ur in user.UserRoles
                        from r in db.Roles
                        where user.role.RoleID == r.RoleID

                        select r.Name;
            if (roles != null)
                return roles.ToArray();
            else
                return new string[] { }; ;
        }
        else
        {
            return new string[] { }; ;
        }
    }
}


> public override bool IsUserInRole(string username, string roleName)
>         {
>             
>             using (EFDbContext db = new EFDbContext())
>             {
>                 User user = db.Users.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.CurrentCultureIgnoreCase)
> || u.Email.Equals(username,
> StringComparison.CurrentCultureIgnoreCase));
> 
>                 if (user != null)
>                 {
>                     var roles = from ur in user.UserRoles
>                                 from r in db.Roles
>                                 where user.role.RoleID == r.RoleID
>                                 //where ur.RoleID == r.RoleID
>                                 select r.Name;
>                     if (user != null)
>                         return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));
>                     else
>                         return false;
>                 }
>                 else
>                 {
>                     return false;
>                 }
>             }
>         }

Я знаю, что мне нужно изменить метод IsUserInRole, чтобы он обрабатывал параметр массива следующим образом: public override bool IsUserInRole(string username, string[] roleName)

Но не знаю, как справиться с этим в linq и главным образом в методе IsUserInRole:

return roles.Any(r => r.Equals(roleName, >StringComparison.CurrentCultureIgnoreCase));

В настоящее время происходит сбой в методе GetRolesForUser, в предложении, где я считаю,

где user.role.RoleID == r.RoleID

сообщение об ошибке отображается ниже:

Уже есть открытый DataReader, связанный с этой Командой, который должен быть закрыт первым. Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.InvalidOperationException: уже существует открытый DataReader, связанный с этой командой, который должен быть закрыт первым.

Ошибка источника:

Строка 66: var role = от ur в user.UserRoles Строка 67: от r в db.Roles Строка 68: где user.role.RoleID == r.RoleID

Спасибо

1 ответ

Несколько ролей могут быть выполнены как таковые: [CustomAuthorize(Roles = "Administrator, User")]Но, увидев, что вы написали этот код, я думаю, вы уже знаете это?

Если все, что вы хотите сделать, это сохранить Users от получения в ваших функциях создания / редактирования / удаления, почему бы не использовать функции авторизации по умолчанию? смысл положить [CustomAuthorize(Roles = "Administrator")] выше редактировать / создавать / удалять и [CustomAuthorize(Roles = "Administrator, User")] превыше всего...

Я угадываю IsUserInRole вызывается при авторизации? Этот метод должен принимать массив string[] roleName, а не просто строку.

Изменить: изменить

                        var roles = from ur in user.UserRoles
                        from r in db.Roles
                       where user.role.RoleID == r.RoleID
                        //where ur.RoleID == r.RoleID
                       select r.Name;

в

var roles = user.UserRoles.select(q=>q.Roles.Name);
Другие вопросы по тегам