Авторизация на основе ролей со списком моделей

У меня есть 3 модели [User, Role и UserRole]

Используйте {ID [PK], имя, адрес электронной почты, пароль, .....}
Роль {ID [PK], Имя, Описание, .......}
UserRole {UserID [FK], RoleID [FK]}

Представьте, что авторизация на основе ролей на контроллере с использованием атрибута [Authorize] указывает, что пользователь должен быть в роли администратора для доступа к любому действию контроллера в классе.

[Authorize(Roles = "Administrator")]
public class PageController : Controller
{
    // Controller code here
}

Это хорошо, что мне нужно,

Есть ли способ назначить мою коллекцию ролей атрибуту [Authorize]? например

Я получу назначенные роли от зарегистрированного пользователя и сохраню их в списке. Можно ли назначить этот список атрибуту [Authorize]? примерно так:

[Authorize(Roles = MyDynamicallyLoadedList)]
public class PageController : Controller
{
    // Controller code here
}

2 ответа

Да.

  1. Переопределить PostAuthenticateRequest в global.asax
  2. Загрузите роли из БД
  3. Создать новый GenericPrincipal
  4. Назначить принципала Thread.CurrentPrincipal а также HttpContext.Current.User

Пример:

protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
    if (User.Identity.IsAuthenticated)
    {
        string[] rolelist = GetRoleListForUserFromAPI(User.Identity.Name);
        HttpContext.Current.User = new GenericPrincipal(User.Identity, rolelist);
        Thread.CurrentPrincipal = HttpContext.Current.User;
    }
}

Ну, две проблемы.

Во-первых, вы не можете использовать список в качестве параметра атрибута. Вместо этого вы можете использовать массив. http://msdn.microsoft.com/fr-fr/library/ms177221%28v=vs.100%29.aspx

Во-вторых, значения параметров атрибутов должны быть известны во время компиляции: содержимое вашего списка будет известно только во время выполнения.

Вы получите сообщение как:

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

Решением было бы создать новый атрибут авторизации (наследуя от AuthorizeAttribute) и переопределить AuthorizedCore

Пример (который вы могли бы адаптировать к вашей проблемной) можно найти здесь

Другие вопросы по тегам