簡體   English   中英

具有角色和權限的 Spring Security

[英]Spring Security with roles and permissions

我正在嘗試使用權限設置基於角色的安全性。 我正在嘗試與 Spring-Security 一起執行此操作。

我不想設置 ACL,因為它似乎對我的要求來說太過分了。

我只想擁有本文所述的簡單權限和角色。 不幸的是,這篇文章沒有描述如何實現給定的解決方案。

有人已經嘗試過這個並且可以指出我正確的方向嗎? 也許還有另一個博客條目描述了實現?

非常感謝。

我是相關文章的作者。

毫無疑問,有多種方法可以做到這一點,但我通常這樣做的方法是實現一個了解角色和權限的自定義UserDetails RolePermission只是您編寫的自定義類。 (沒有fancy-- Role都有一個名稱和一組Permission的情況下,和Permission都有一個名稱。)然后getAuthorities()返回GrantedAuthority對象是這個樣子的:

PERM_CREATE_POSTPERM_UPDATE_POSTPERM_READ_POST

而不是返回諸如

ROLE_USER , ROLE_MODERATOR

如果您的UserDetails實現具有getRoles()方法,則角色仍然可用。 (我建議有一個。)

理想情況下,您為用戶分配角色,並自動填寫相關的權限。 這將涉及擁有一個知道如何執行該映射的自定義UserDetailsService ,並且它所要做的就是從數據庫中獲取映射。 (有關架構,請參閱文章。)

然后,您可以根據權限而不是角色來定義您的授權規則。

希望有幫助。

要實現這一點,您似乎必須:

  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 來完成該操作,這將為用戶檢索正確的角色。

希望這次我得到了你要找的東西。 祝你好運。

基本步驟是:

  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; }

當然,從這里您可以針對您的特定要求應用大量優化/自定義。

這是最簡單的方法。 允許組權限以及用戶權限。

-- 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM