[英]Spring Security with roles and permissions
我正在嘗試使用權限設置基於角色的安全性。 我正在嘗試與 Spring-Security 一起執行此操作。
我不想設置 ACL,因為它似乎對我的要求來說太過分了。
我只想擁有本文所述的簡單權限和角色。 不幸的是,這篇文章沒有描述如何實現給定的解決方案。
有人已經嘗試過這個並且可以指出我正確的方向嗎? 也許還有另一個博客條目描述了實現?
非常感謝。
我是相關文章的作者。
毫無疑問,有多種方法可以做到這一點,但我通常這樣做的方法是實現一個了解角色和權限的自定義UserDetails
。 Role
和Permission
只是您編寫的自定義類。 (沒有fancy-- Role
都有一個名稱和一組Permission
的情況下,和Permission
都有一個名稱。)然后getAuthorities()
返回GrantedAuthority
對象是這個樣子的:
PERM_CREATE_POST
、 PERM_UPDATE_POST
、 PERM_READ_POST
而不是返回諸如
ROLE_USER
, ROLE_MODERATOR
如果您的UserDetails
實現具有getRoles()
方法,則角色仍然可用。 (我建議有一個。)
理想情況下,您為用戶分配角色,並自動填寫相關的權限。 這將涉及擁有一個知道如何執行該映射的自定義UserDetailsService
,並且它所要做的就是從數據庫中獲取映射。 (有關架構,請參閱文章。)
然后,您可以根據權限而不是角色來定義您的授權規則。
希望有幫助。
要實現這一點,您似乎必須:
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 來完成該操作,這將為用戶檢索正確的角色。
希望這次我得到了你要找的東西。 祝你好運。
基本步驟是:
使用自定義身份驗證提供程序
<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; }
當然,從這里您可以針對您的特定要求應用大量優化/自定義。
這是最簡單的方法。 允許組權限以及用戶權限。
-- 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>
只是為了完整起見(也許其他人不必從頭開始實現它):
和其他人一樣,我們已經實現了我們自己的小型圖書館。 它應該讓事情變得更容易,這樣我們的開發人員就不必每次都重新實現它。 如果 spring security 能夠提供開箱即用的 rbac 支持那就太好了,因為這種方法比基於默認權限的方法要好得多。
看看Github (OSS,MIT 許可證),看看它是否適合您的需求。 它基本上只解決角色 <-> 權限映射。 您必須自己提供的缺失部分基本上是用戶 <-> 角色映射,例如通過將組(racf/ad 組)映射到角色 (1:1) 或通過實施附加映射。 那個在每個項目中都不一樣,所以提供一些實現是沒有意義的。
我們基本上已經在內部使用了它,因此我們可以從一開始就使用 rbac。 如果應用程序不斷增長,我們仍然可以稍后用其他一些實現替換它,但對我們來說在開始時正確設置很重要。
如果您不使用 rbac,則權限很可能分散在整個代碼庫中,稍后您將很難將它們提取/分組(到角色中)。 生成的圖也有助於稍后對其進行推理/重組。
ACL 對我的要求也太過分了。
我最終創建了一個類似於GrantedAuthority
的庫,以根據用戶的角色成員身份為 Role->Permissions 注入GrantedAuthority
列表。
例如,使用數據庫來保存關系 -
@Autowired
RolePermissionsRepository repository;
public void setup(){
String roleName = "ROLE_ADMIN";
List<String> permissions = new ArrayList<String>();
permissions.add("CREATE");
permissions.add("READ");
permissions.add("UPDATE");
permissions.add("DELETE");
repository.save(new RolePermissions(roleName, permissions));
}
在當前安全會話中注入 Authentication 對象時,它將具有原始角色/授予的權限。
這個庫為 Spring Security 提供了 2 個內置的集成點。 當到達集成點時,將調用 PermissionProvider 以獲取用戶所屬的每個角色的有效權限。
不同的權限列表被添加為 Authentication 對象中的 GrantedAuthority 項目。
例如,您還可以實現自定義PermissionProvider
以將關系存儲在配置中。
更完整的解釋在這里 - https://stackoverflow.com/a/60251931/1308685
源代碼在這里 - https://github.com/savantly-net/spring-role-permissions
閱讀這篇文章后,來自 Baeldung。 我發現解決方案非常簡單。
我所做的是將角色和權限添加到 GrantedAuthority 中。 我能夠訪問兩種方法 hasRole() 和 hasAuthority()。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.