Spring Security: как изменить роли пользователя без входа и выхода - PullRequest
0 голосов
/ 29 мая 2018

Spring Security 4.2.4.Java 8

Мне нужно изменить права пользователей без повторной регистрации.Это мой сервис:

@Component
public class AuthoritiesUpdater {

    private final UserRoleService userRoleService;

    @Autowired
    public AuthoritiesUpdater(UserRoleService userRoleService) {
        this.userRoleService = userRoleService;
    }

    public void update(User user) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        List<UserRole> userRoles = userRoleService.findByUser(user);

        List<GrantedAuthority> actualAuthorities = userRoles.stream().map(userRole -> new 
SimpleGrantedAuthority(userRole.getRole())).collect(Collectors.toList());

        Authentication newAuth = new 
UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), actualAuthorities);

        SecurityContextHolder.getContext().setAuthentication(newAuth);
    }
}

Но есть проблема.Мне нужно изменить роли для любого пользователя.Допустим, я менеджер и хочу поменять роль для тестового пользователя.Мне нужно перезагрузить разрешения после сохранения конфигурации, и у тестового пользователя появятся новые роли, когда он нажмет кнопку F5 и перезагрузит страницу без повторного входа.Но SecurityContextHolder.getContext().getAuthentication(); возвращает объект аутентификации только для текущего пользователя (менеджера).Мне нужно получить объект аутентификации для измененного пользователя для вызова new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), actualAuthorities);.Могу ли я получить объект аутентификации для любого пользователя или я могу решить эту проблему другим способом?Может быть, я могу получить объект аутентификации, использующий реестр сеансов?

PS: выполнение сеанса с истекшим сроком действия для пользователя не является хорошим вариантом.

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Отличный ответ, спасибо @virkom!

Для новых пользователей следующие шаги:

  1. Создайте список полномочий, которые вы хотите иметь у пользователя (включая предыдущие (и те), которые у него были),В этом случае (ниже) я создал набор, чтобы они были уникальными.

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

  3. Обновите контекст безопасности с помощью новой информации для аутентификации.Это будет иметь эффект обновления учетных данных пользователя.

Ниже приведен фрагмент кода:

Set<GrantedAuthority> authorities = new HashSet<>();
authorities.add(new SimpleGrantedAuthority("USER"));
authorities.add(new SimpleGrantedAuthority("ADMIN"));

Authentication reAuth = new UsernamePasswordAuthenticationToken("user",new 

BCryptPasswordEncoder().encode("password"),authorities);  

SecurityContextHolder.getContext().setAuthentication(reAuth);

Пример кода доступен на github: https://github.com/aoa4eva/ContextDemo

0 голосов
/ 29 мая 2018

Решение немного проще, чем я думал.У меня есть пользователь.И я могу позвонить UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword(), actualAuthorities); вместо UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), actualAuthorities);.Мне не нужно получать объект аутентификации.Финальная версия услуги:

@Component
public class AuthoritiesUpdater {

    private final UserRoleService userRoleService;

    @Autowired
    public AuthoritiesUpdater(UserRoleService userRoleService) {
        this.userRoleService = userRoleService;
    }

    public void update(User user) {
        List<UserRole> userRoles = userRoleService.findByUser(user);

        List<GrantedAuthority> actualAuthorities = userRoles.stream().map(userRole -> new SimpleGrantedAuthority(userRole.getRole())).collect(Collectors.toList());

        Authentication newAuth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), actualAuthorities);

        SecurityContextHolder.getContext().setAuthentication(newAuth);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...