Плагин Grails Spring Security - изменяйте авторизованные права пользователя - PullRequest
8 голосов
/ 20 июня 2011

У меня есть простое приложение Grails с установленным и работающим плагином Spring Security Core.Тем не менее, я не нашел решения проблемы с обновлением авторизованных пользователей в контексте безопасности.Я не говорю об обновлении данных текущего пользователя (например, springSecurityService.reauthenticate).

Моя проблема: у меня есть простое приложение для управления пользователями с использованием полномочий ROLE_ADMIN и ROLE_USER.Теперь у меня есть два администратора, вошедшие в систему одновременно (с правами ROLE_ADMIN) с разных компьютеров, и один администратор решает изменить права другого администратора с ROLE_ADMIN на ROLE_USER.

Как я могу обновить пользователя и рольчтобы измененный пользователь (с новой ролью ROLE_USER) не мог выполнить никаких действий уровня ROLE_ADMIN и был немедленно перенаправлен на страницы уровня ROLE_USER?Есть ли способ обновить контекст безопасности, чтобы мне не приходилось делать дополнительную проверку во всех действиях контроллера, были ли изменены права доступа вошедшего в систему пользователя?Могу ли я использовать для этого свойство cahceUsers?Я не модифицировал cacheUsers и, по моему мнению, по умолчанию это false.Пожалуйста, исправьте меня, если я ошибаюсь.

РЕДАКТИРОВАТЬ: последовательность, которая вызывает проблему:

  1. Администратор "A" изменяет администратор "B" и устанавливает новыйроль (ROLE_USER) для администратора "B"

  2. код вызывает PersonRole.removeAll(personInstanceB) and PersonRole.create(personInstanceB, roleAdmin) и все обновляется в обычном режиме

  3. одновременно "Администратор"B "уже вошел в систему, когда их полномочия изменены.Администратор "B" может продолжать работать на страницах с ограниченным доступом ROLE_ADMIN до тех пор, пока он не выйдет из системы и не выполнит новый вход в систему.Только после этого полномочия обновляются, и администратор "B" получает новую роль (ROLE_USER)

  4. Я хочу, чтобы администратор "B" перенаправлялся на страницы ROLE_USER, когда пользователь обновляется с помощьюновая роль, а не только после выхода из системы / входа в систему

  5. вызов springSecurityService.reauthenticate personInstanceB.username) приводит к тому, что администратор "A" "входит в систему" как администратор "B", поэтому это не работает.

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

Cheers, mizzzto

Ответы [ 2 ]

11 голосов
/ 20 июня 2011

Это не проверено, но попробуйте

В вашем контроллере / классе обслуживания,

...

User user = User.get(springSecurityService.principal.id) //get the user
Role adminRole = //get or create the admin Role
UserRole.remove user, role // remove admin Role

Role userRole = // get or create the user Role
UserRole.create user, role //add the user Role

... 

if (!user.hasErrors() && user.save(flush: true)) {
    springSecurityService.reauthenticate user.username // refresh the users security deatils
}

....

РЕДАКТИРОВАТЬ

Теперь все намного понятнее.

То, что я хотел бы сделать с моей головы, это использовать функцию переключения пользователя.см. Смена пользователя

  • Сначала вы установите для атрибута useSwitchUserFilter значение true
  • Рекомендуется создать новую роль (например, ROLE_SWITCH_USER).для этой привилегии.
  • где-нибудь на вашей странице администратора,

    <sec:ifAllGranted roles='ROLE_SWITCH_USER'>
       <form action='/j_spring_security_switch_user' method='POST'>
          Switch to user: <input type='text' name='j_username'/> <br/>
          <input type='submit' value='Switch'/>
       </form>
    </sec:ifAllGranted>
    
  • войдите в систему как пользователь, которого вы хотите редактировать, используя свое имя пользователя
  • changeих настройки роли путем вызова метода adminToUser() ниже (например)
  • , чтобы вернуться к исходному пользователю
  • Готово.

- Выможно использовать код формы первого ответа для создания метода в вашем контроллере или службе, который принимает userInstance и меняет свою роль с admin на пользователя.

def adminToUser(user, adminRole, userRole){
    UserRole.remove user, adminRole
    UserRole.create user, userRole 
    if (!user.hasErrors() && user.save(flush: true)) {
        springSecurityService.reauthenticate user.username 
    }
}
6 голосов
/ 08 ноября 2012

Я решил эту проблему, повторно аутентифицировавшись дважды:

Сохраните имя администратора, который понижает права другого пользователя:

def originalUserName = springSecurityService.principal.name
springSecurityService.reauthenticate user.username
springSecurityService.reauthenticate originalUserName
...