Spring Security с ролями и разрешениями - PullRequest
76 голосов
/ 15 июня 2011

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

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

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

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

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

Ответы [ 5 ]

75 голосов
/ 27 января 2012

Я автор рассматриваемой статьи.

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

PERM_CREATE_POST, PERM_UPDATE_POST, PERM_READ_POST

вместо возврата таких вещей, как

ROLE_USER, ROLE_MODERATOR

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

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

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

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

30 голосов
/ 16 июня 2011

Для реализации этого, похоже, вам необходимо:

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

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

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

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

6 голосов
/ 16 июня 2011

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

  1. Использование настраиваемого поставщика проверки подлинности

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

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

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

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

5 голосов
/ 15 июля 2013

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

-- 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>
0 голосов
/ 26 февраля 2019

Просто ради полноты (может быть, кому-то еще не придется реализовывать это с нуля):

Мы внедрили нашу собственную маленькую библиотеку, как и все остальные. Это должно упростить ситуацию, чтобы нашим разработчикам не приходилось каждый раз переопределять это. Было бы здорово, если бы Spring Security обеспечивал поддержку rbac из коробки, так как этот подход намного лучше, чем стандартный, основанный на разрешениях.

Взгляните на Github (лицензия OSS, MIT), чтобы убедиться, что он соответствует вашим потребностям. В основном это касается отображения ролей <-> привилегий. Недостающая часть, которую вы должны предоставить самостоятельно, - это, в основном, отображение пользовательских <-> ролей, например, сопоставляя группы (racf / группы объявлений) с ролями (1: 1) или реализуя дополнительное сопоставление. Это отличается в каждом проекте, поэтому не имеет смысла предоставлять какую-то реализацию.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...