Мы разрабатываем приложение (использующий безопасность Spring Grails (раньше Acegi)), в котором у нас будут тысячи пользователей, которые охватывают 10-15 осторожных пользовательских типов. В существующей системе каждый пользовательский тип приравнивается к "группе", и определенные роли и полномочия связываются с группой. Пользователь получает все их "роли" от группы.
Например, у нас могло бы быть две группы пользователей:
КЛОУН: роли = ride_clown_car, toot_horn, receive_applause Acrobat: роли = do_flip, walk_tightrope, receive_applause
У нас есть три пользователя, один присвоенный группе КЛОУНА, один присвоенный группе Acrobat и один присвоенный и к (имеет объединение КЛОУНА и к ролей Acrobat).
Если мы изменяем полномочия, мы делаем так на уровне группы. Например, если мы добавим swing_on_trapeze разрешение к группе Acrobat, то все акробаты автоматически наследуют ее.
В терминах Grails полномочия на контроллерах все еще были бы на ролевом уровне. Так действие с @Secured (['toot_horn']) позволил бы пользователям в группе КЛОУНА, но не в группе Acrobat. @Secured (['receive_applause']) позволил бы и КЛОУНАМ и АКРОБАТАМ.
Как я сделал бы это в безопасности Spring, учитывая двухмногоуровневую природу модели (пользователь, роль)? Я должен реализовать свою собственную аутентификацию для сбора ролей, базирующихся через группы?
Спасибо!
Вам следует использовать новый Spring Security Core плагин, так как плагин Acegi не разрабатывается и в основном устарел.
Но в любом случае, оба плагина ожидают, что в вашем классе пользователя есть что-то вроде getAuthorities()
метода, который возвращает экземпляры ролей. В сценарии вроде этого, где у пользователя много групп, просто соберите все роли групп:
class User {
...
def getAllRoles() {
Set allRoles = []
groups.each { allRoles.addAll it.roles }
allRoles
}
}
Это предполагает, что у вас есть много-ко-многим между User и Group:
static hasMany = [groups: Group]
и у Group есть много-ко-многим с Role:
static hasMany = [roles: Role]
Чтобы использовать это, установите свойство 'relationalAuthorities' в 'allRoles' в SecurityConfig. groovy, чтобы он использовал его вместо свойства "многие ко многим" между пользователем и ролью:
relationalAuthorities='allRoles'
Для плагина Spring Security core не требуется конфигурация, поскольку он уже зависит от определенного приложением метода getAuthorities, поэтому просто используйте что-то вроде этого в классе User:
Set<Role> getAuthorities() {
Set allRoles = []
groups.each { allRoles.addAll it.roles }
allRoles
}