Keycloak:如何设置和限制每个用户的资源服务器范围

huangapple go评论70阅读模式
英文:

Keycloak: how to set and restrict scopes of resource server per user

问题

我正在开发一个Spring Boot 3和Spring Security 6的应用程序。该应用程序是一个REST API。我将使用Spring Security和Spring Security资源服务器进行授权。端点将使用@PreAuthorize("hasAuthority('SCOPE_scope-name')")进行注释以限制访问。我想要使用OIDC和JWT。

我将使用Keycloak作为授权服务器。现在,我想要限制特定用户组对资源/ API的访问。假设我有用户a、b、c和x、y。用户a、b、c将具有对read:testwrite:test范围的访问权限。但是用户x、y只能访问read:test范围。即使用户x、y请求write:test范围,Keycloak也不会授予这些用户该范围。

最好的情况是,我想使用用户组来轻松管理用户。最好创建一些角色并分配给用户组。每个角色将具有一组允许访问的范围。我尝试阅读文档,但对我来说很困惑。范围和角色位于不同的位置。我不明白如何实现我想要做的事情。

根据Spring Security文档,在application.properties文件中,我只需要设置spring.security.oauth2.resourceserver.jwt.issuer-uri。我不明白Keycloak/Spring应用程序如何仅通过issuer-uri设置知道这是哪个客户端/资源服务器。

在Keycloak中,我如何设置和管理资源服务器的API端点的范围,并限制每个用户的范围?

英文:

I am developing a spring boot 3 and spring security 6 application. The application is rest api. I will use spring security, spring security resource sever for authorization. Endpoint will be annotated with @PreAuthorize("hasAuthority('SCOPE_scope-name')") to restrict access to it. I want to use OIDC, JWT.

I will use keycloak as the authorization server. Now, I want to restrict access to resources/api for specific user groups. Suppose I have user a,b,c and x,y. User a,b,c will have access to scopes read:test and write:test. But users x,y will only have access to scope read:test. Even if user x,y asks for the write:test scope, keycloak will not give the scope to these users.

Preferably I want to use user groups to easily manage the users. Preferably some roles will be created and assigned to user groups. Each role will have some set of scopes that the role will allow access to. I tried reading the documentation. It was confusing to me. There are scopes and roles in different places. I did not understand how can I achieve what I want to do.

According to spring security documentation, In the application.properties file I just have to set spring.security.oauth2.resourceserver.jwt.issuer-uri. I do not understand how keycloak/spring application will know which client/resource server is this application from just the issuer-uri settings.

In keycloak, how do I set, manage scopes for API endpoint for a resource server, and restrict those scopes per user?

答案1

得分: 2

以下是翻译好的内容:

范围不是角色

您可能会看到:

  • 角色是用户被允许执行的操作
  • 范围是客户端代表用户被允许执行的操作

OAuth2规范定义了范围,但与角色、组、权限、授权或用户访问表示无关。授权服务器供应商使用私有声明来处理这些。

默认情况下,Keycloak使用 realm_access.rolesresource_access.{client-ID}.roles,但您可以定义自己的映射器来使用任何您喜欢的声明。

将Keycloak角色转换为Spring权限

由于OAuth2中没有角色的标准,Spring默认权限转换器使用范围声明作为源,并在每个条目前加上 SCOPE_ 前缀。

这很少令人满意,您经常需要提供自己的权限转换器

完整的工作示例

请参考我的教程。除了工作示例外,您还会找到一些您似乎缺少的OAuth2/OpenID背景信息。

英文:

Scopes Are Not Roles

You may see:

  • roles as what a user is allowed to do
  • scope as what a client is allowed to do on behalf of a user

Scope is defined the OAuth2 spec, but there is nothing about roles, groups, permissions, grants or whatever user access representation. Authorization servers vendors use private claims for that.

By default, Keycloak uses realm_access.roles and resource_access.{client-ID}.roles, but you may define your own mappers to use any claim you like.

Converting Keycloak Roles to Spring Authorities

As there is no standard for roles in OAuth2, Spring default authorities converter uses scope claim as source and prefixes each entry with SCOPE_.

This is rarely satisfying and you frequently need to provide with your own authorities converter.

Complete Working Samples

Refer to my tutorials. In addition to working samples, you'll find some of the OAuth2 / OpenID background you seem to be missing.

答案2

得分: 1

Scopes are fixed at design time and do not provide a full authorization solution. When you want dynamic authorization per user, you must use claims instead. Arrange users into roles however you would like. In Keycloak, at the time of token issuance, include values such as these in tokens:

{
  scope: orders,
  role: customer,
  access_level: read
}

More generally think of a scope representing a business area and being composed of claims. Look into Keycloak claims mappers for the vendor specific way to manage this.

USING CLAIMS

Your Spring resource server will then just receive such values in the authenticated principal, after validating the JWT access token. You can then use these values in the API's business authorization code.

Here is some example code of mine, to give you an idea of how claims can be injected then used for business authorization. Annotations may work to deny access in some cases. In others you will need to do things like filter collections to contain only authorized items.

英文:

Scopes are fixed at design time and do not provide a full authorization solution. When you want dynamic authorization per user, you must use claims instead. Arrange users into roles however you would like. In Keycloak, at the time of token issuance, include values such as these in tokens:

{
  scope: orders,
  role: customer,
  access_level: read
}

More generally think of a scope representing a business area and being composed of claims. Look into Keycloak claims mappers for the vendor specific way to manage this.

USING CLAIMS

Your Spring resource server will then just receive such values in the authenticated principal, after validating the JWT access token. You can then use these values in the API's business authorization code.

Here is some example code of mine, to give you an idea of how claims can be injected then used for business authorization. Annotations may work to deny access in some cases. In others you will need to do things like filter collections to contain only authorized items.

huangapple
  • 本文由 发表于 2023年6月6日 10:38:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76411111.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定