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>