@Biaci_Anj

Почему Role и Privileges выдаются в UserDetailsService в одной коллекции, как равноценные понятия в данном примере?

К примеру, вот у меня есть два Entity Privilege и Role. Они взаимосвязаны
@ManyToMany

Лишние подробности ( конструкторы, методы ) пропущены для краткости.

public class Privilege extends AbstractBaseEntity {
    private String name;
    @ManyToMany(mappedBy = "privileges")
    private Collection<Role> roles;


public class Role extends AbstractBaseEntity {
    private String name;

    @ManyToMany(mappedBy = "roles")
    private Collection<User> users;


    @ManyToMany
    @JoinTable(name = "roles_privileges", joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id"))
    private Collection<Privilege> privileges;
}

У User есть просто коллекция Roles

public class User extends AbstractBaseEntity{
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private Collection<Role> roles;


А теперь то, что я не понимаю абсолютно:
У нас при loadUserByUsername в конструкторе для User в GrantedAuthority мы выдаем
role.getName() и role.getPrivileges().getName(). Т.е. мы мешаем имя роли и имена привилегий для этой роли в одну кучу.
Если роль в теории должна быть контейнером для привилегий, то зачем нам класть в GrantedAuthorities имя роли, почему не оставлять одни привилегии?

public class MyUserDetailsService implements UserDetailsService {
    private User user;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        return new org.springframework.security.core.userdetails.User(
                user.getEmail(), user.getPassword(), user.isEnabled(),
                true, true, true,
                getAuthorities(user.getRoles()));
    }

    private Collection<? extends GrantedAuthority> getAuthorities(final Collection<Role> roles) {
        return getGrantedAuthorities(getPrivileges(roles));
    }

    private List<String> getPrivileges(final Collection<Role> roles) { // Просто возвращает
        // коллекцию role.getName() и role.getPrivileges().getName в одной Коллекции
        final List<String> rolePrivilegesAndNames = new ArrayList<>();
        final List<Privilege> rolePrivileges = new ArrayList<>();

        for (final Role role : roles) {
            rolePrivilegesAndNames.add(role.getName());
            rolePrivileges.addAll(role.getPrivileges());
        }

        for (final Privilege privilege : rolePrivileges) {
            rolePrivilegesAndNames.add(privilege.getName());
        }

        return rolePrivilegesAndNames;
    }

    private List<GrantedAuthority> getGrantedAuthorities(final List<String> privileges) {
        // Переделывает List String в List GrantedAuthority
        final List<GrantedAuthority> authorities = new ArrayList<>();
        for (final String privilege : privileges) {
            authorities.add(new SimpleGrantedAuthority(privilege));
        }
        return authorities;
    }
}
  • Вопрос задан
  • 51 просмотр
Решения вопроса 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Добрый день.
Собственно говоря, в той же статье откуда вы взяли код (baeldung) ниже написана причина смешивания ролей и привилегий.
The interesting thing to follow here is how the Privileges (and Roles) are mapped to GrantedAuthority entities.This mapping makes the entire security configuration highly flexible and powerful – you can mix and match roles and privileges as granular as necessary, and at the end, they'll be correctly mapped to authorities and returned back to the framework.


Вот, еще полезная информация (прочитайте первый ответ) - https://stackoverflow.com/questions/6357579/spring...

В Spring есть понятие Authority. Это могут быть как роли, так и привилегии (privilege, permission). Так как конечная цель заключается в том, чтобы проверить права пользователя и так как привилегия и роль по факту являются теми самыми "правами", но лишь на разных уровнях абстракции (роль содержит сет привилегий), то в примере кода, который вы указали все смешано в одну кучу.
Отличие проявляется на другом уровне, когда есть метод для проверки роли hasRole(), к слову, к значению этого метода автоматически добавляется префикс ROLE_, а также метод hasAuthority(), когда проверяются все права (роли и привилегии) и в этом случае для проверки роли нужно указывать префикс ROLE_ самому или уже указать название привилегии (например, READ_PRIVILEGE).
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы