Spring Безопасность с ролями и разрешениями

Я пытаюсь настроить защиту на основе ролей с разрешениями. Я пытаюсь сделать это вместе с Spring -Security.

Я не хочу настраивать ACL, поскольку это кажется излишним для моих требований.

Я просто хочу иметь простые разрешения и роли, описанные в этой статье . К сожалению, в статье не описывается, как реализовать данное решение.

Кто-то уже пробовал это и может указать мне в правильном направлении? Может быть, есть еще одна запись в блоге, в которой описывается реализация?

Большое спасибо.

Ответ 1

Чтобы реализовать это, кажется, что вам нужно:

  • Создайте свою модель (пользователь, роль, разрешения) и способ получения разрешений для данного пользователя;
  • Определите свой собственный org.springframework.security.authentication.ProviderManager и настройте его (установите его поставщиков) в пользовательский org.springframework.security.authentication.AuthenticationProvider. Этот последний должен вернуть свой метод аутентификации Authentication, который должен быть установлен с помощью org.springframework.security.core.GrantedAuthority, в вашем случае, всех разрешений для данного пользователя.

Уловкой в ​​этой статье является назначение ролей для пользователей, но для установки разрешений для этих ролей в объекте Authentication.authorities.

Для этого я советую вам прочитать API и посмотреть, можно ли расширить основной ProviderManager и AuthenticationProvider вместо того, чтобы все реализовать. Я сделал это с org.springframework.security.ldap.authentication.LdapAuthenticationProvider, установив пользовательский LdapAuthoritiesPopulator, который будет получать правильные роли для пользователя.

Надеюсь, на этот раз я получил то, что вы ищете. Удачи.

Ответ 2

Я автор данной статьи.

Несомненно, есть несколько способов сделать это, но, как я обычно это делаю, это реализовать пользовательский UserDetails, который знает о ролях и разрешениях. Role и Permission - это только пользовательские классы, которые вы пишете. (Ничего необычного - Role имеет имя и набор экземпляров Permission, а Permission имеет имя.) Затем getAuthorities() возвращает объекты GrantedAuthority, которые выглядят следующим образом:

PERM_CREATE_POST, PERM_UPDATE_POST, PERM_READ_POST

вместо того, чтобы возвращать такие вещи, как

ROLE_USER, ROLE_MODERATOR

Роли по-прежнему доступны, если ваша реализация UserDetails имеет метод getRoles(). (Я рекомендую иметь его.)

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

Затем вы можете определить свои правила авторизации с точки зрения разрешений вместо ролей.

Надеюсь, что это поможет.

Ответ 3

Основные шаги:

  • Использовать собственный поставщик проверки подлинности

    <bean id="myAuthenticationProvider" class="myProviderImplementation" scope="singleton">
    ...
    </bean>
    

      

  • Сделайте свой пользовательский поставщик возвратом пользовательской реализации UserDetails. Этот UserDetailsImpl будет иметь getAuthorities() следующим образом:

    public Collection<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> permissions = new ArrayList<GrantedAuthority>();
        for (GrantedAuthority role: roles) {
            permissions.addAll(getPermissionsIncludedInRole(role));
        }
        return permissions;
    }
    

Конечно, здесь вы можете применить множество оптимизаций/настроек для своих конкретных требований.

Ответ 4

Это самый простой способ сделать это. Позволяет властям группы, а также полномочиям пользователей.

-- Postgres syntax

create table users (
  user_id serial primary key,
  enabled boolean not null default true,
  password text not null,
  username citext not null unique
);

create index on users (username);

create table groups (
  group_id serial primary key,
  name citext not null unique
);

create table authorities (
  authority_id serial primary key,
  authority citext not null unique
);

create table user_authorities (
  user_id int references users,
  authority_id int references authorities,
  primary key (user_id, authority_id)
);

create table group_users (
  group_id int references groups,
  user_id int referenecs users,
  primary key (group_id, user_id)
);

create table group_authorities (
  group_id int references groups,
  authority_id int references authorities,
  primary key (group_id, authority_id)
);

Затем в META-INF/applicationContext-security.xml

<beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder" />

<authentication-manager>
    <authentication-provider>

        <jdbc-user-service
                data-source-ref="dataSource"

                users-by-username-query="select username, password, enabled from users where username=?"

                authorities-by-username-query="select users.username, authorities.authority from users join user_authorities using(user_id) join authorities using(authority_id) where users.username=?"

                group-authorities-by-username-query="select groups.id, groups.name, authorities.authority from users join group_users using(user_id) join groups using(group_id) join group_authorities using(group_id) join authorities using(authority_id) where users.username=?"

                />

          <password-encoder ref="passwordEncoder" />

    </authentication-provider>
</authentication-manager>