Авторизация на основе ролей со списком моделей
У меня есть 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 ответа
Да.
- Переопределить PostAuthenticateRequest в global.asax
- Загрузите роли из БД
- Создать новый
GenericPrincipal
- Назначить принципала
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
Пример (который вы могли бы адаптировать к вашей проблемной) можно найти здесь