keycloak 中的资源、范围、权限和策略 [英] Resources, scopes, permissions and policies in keycloak

查看:32
本文介绍了keycloak 中的资源、范围、权限和策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Keycloak 的授权系统创建一个相当简单的基于角色的访问控制系统.Keycloak 正在替换的系统允许我们创建一个用户",他是一个或多个组"的成员.在这个遗留系统中,用户被授予权限"来访问大约 250 项能力"中的每一项,无论是通过组成员身份(组被分配权限)还是直接授予用户权限.

我想将旧系统映射到 keycloak 授权.

将现有系统中的每个功能"映射到一个 keycloak 资源和一组 keycloak 范围对我来说应该很简单.例如,viewAccount"功能显然会映射到帐户"资源和视图"范围;并且viewTransaction"映射到交易"资源......但是最好的做法是创建一个视图"范围,并在多个资源(账户、交易等)中使用它吗?或者我应该创建viewAccount"范围、viewTransaction"范围等吗?

同样,我对权限有点困惑.对于资源和范围的每个实际组合,创建权限是否是通常的做法?如果有多个权限匹配给定的资源/范围,Keycloak 会做什么?我猜测 Keycloak 的目的是允许我针对资源和范围配置权限矩阵,例如,我可以有权访问帐户"和查看"范围的权限,因此我将获得权限查看帐户?

我问是因为这一切的结果似乎是我旧的viewAccount"功能最终创建了一个Account"资源,具有View"范围和viewAccount"权限,这似乎让我回到了哪里我曾是.没问题,如果正确的话.

最后,显然我需要一组确定是否应应用 viewAccount 的策略.但是,这是否意味着我需要为用户可能属于的每个遗留组制定策略?例如,如果我有一个帮助台"角色,那么我需要一个帮助台成员"策略,然后我可以将其添加到viewAccount"权限中.这是正确的吗?

谢谢,

标记

解决方案

我知道我迟到了 2 年以上,但我想我会分享我所知道的,并希望为未来的读者减轻一些痛苦.完全透明——我绝不是 Keycloak/OAuth/OIDC 专家,我所知道的主要是通过阅读文档、书籍、优秀的 YouTube 和使用该工具.

这篇文章将由两部分组成:

  1. 我会尽力回答你所有的问题
  2. 我将向您展示如何在 Keycloak 中使用策略/范围/权限,而无需部署单独的应用程序,以便更好地理解该线程中的一些核心概念.请注意,这主要是为了让您入门.我正在使用 Keycloak 8.0.0.

第一部分

开始之前的一些术语:

  • 在 Keycloak 中,您可以创建两种类型的权限:

    1. 这是有道理的,因为我们只允许两个角色通过 Only Bank Teller and Account Owner Policy 访问该资源.让我们测试一下,以确保这是真的!
    2. 点击评价结果正上方的返回链接
    3. 将 bob 的角色更改为 account_owner,然后点击 Evaluate.您现在应该看到结果为 PERMIT.如果您返回并将角色更改为 bank_teller

    请参阅评估和测试政策

    创建基于范围的权限

    1. 返回权限部分
    2. 这次在 Create Permission 下拉菜单下选择 Scope-Based.
    3. Name下,输入View Account Scope Permission
    4. Scopes下,输入account:view
    5. Apply Policy下,输入Only Account Owner Policy
    6. 确保Decision Strategy设置为Unanimous
    7. 点击保存

    请参阅创建基于范围的权限

    第二次试运行

    评估我们的新变化

    1. 回到Authorization部分
    2. 点击评估
    3. 用户应该是 bob
    4. 角色应该是 bank_teller
    5. Resources 应该是View Account Resource 然后点击Add
    6. 点击Evaluate,我们应该得到DENY.
      • 同样,这应该不足为奇,因为 bank_teller 可以访问 resource 而不是 scope.这里一个权限评估为真,另一个为假.鉴于资源服务器的Decision Strategy设置为Unanimous,最终决策为DENY.
    7. 点击Authorization标签下的Settings,将Decision Strategy改为Affirmative,返回再次执行步骤 1-6.这一次,最终的结果应该是PERMIT(一个权限为真,所以最终决定为真).
    8. 为了完整起见,将资源服务器的Decision Strategy 改回Unanimous.再次返回第 1 步到第 6 步,但这次将角色设置为 account_owner.这一次,最终结果再次是 PERMIT,这是有道理的,因为 account_owner 可以访问 resourcescope.

    Neat :) 希望这会有所帮助.

    I want to create a fairly simple role-based access control system using Keycloak's authorizaion system. The system Keycloak is replacing allows us to create a "user", who is a member of one or more "groups". In this legacy system, a user is given "permission" to access each of about 250 "capabilities" either through group membership (where groups are assigned permissions) or a direct grant of a permission to the user.

    I would like to map the legacy system to keycloak authorizations.

    It should be simple for me to map each "capability" in the existing system to a keycloak resource and a set of keycloak scopes. For example, a "viewAccount" capability would obviously map to an "account" resource and a "view" scope; and "viewTransaction" maps to a "transaction" resource... but is it best practice to create just one "view" scope, and use it across multiple resources (account, transaction, etc)? Or should I create a "viewAccount" scope, a "viewTransaction" scope, etc?

    Similarly, I'm a little confused about permissions. For each practical combination of resource and scope, is it usual practice to create a permission? If there are multiple permissions matching a given resource/scope, what does Keycloak do? I'm guessing that the intention of Keycloak is to allow me to configure a matrix of permissions against resources and scopes, so for example I could have permission to access "accounts" and permission for "view" scope, so therefore I would have permission to view accounts?

    I ask because the result of all this seems to be that my old "viewAccount" capability ends up creating an "Account" resource, with "View" scope, and a "viewAccount" permission, which seems to get me back where I was. Which is fine, if it's correct.

    Finally, obviously I need a set of policies that determine if viewAccount should be applied. But am I right that this means I need a policy for each of the legacy groups that a user could belong to? For example, if I have a "helpdesk" role, then I need a "helpdesk membership" policy, which I could then add to the "viewAccount" permission. Is this correct?

    Thanks,

    Mark

    解决方案

    I know I'm 2+ years late but I figure I'd share what I know and hopefully alleviate some pain for future readers. Full transparency- I am by no means a Keycloak/OAuth/OIDC expert and what I know is mostly from reading the docs, books, good ol' YouTube and playing around with the tool.

    This post will be comprised of two parts:

    1. I'll attempt to answer all your questions to the best of my ability
    2. I'll show you all how you can play around with policies/scopes/permissions in Keycloak without needing to deploy a separate app in order to better understand some of the core concepts in this thread. Do note though that this is mostly meant to get you all started. I'm using Keycloak 8.0.0.

    Part I

    Some terminology before we get started:

    • In Keycloak, you can create 2 types of permissions: Resource-Based and Scope-Based.
    • Simply put, for Resource-Based permissions, you apply it directly to your resource
    • For Scoped-Based permission, you apply it to your scope(s) or scope(s) and resource.

    is it best practice to create just one "view" scope, and use it across multiple resources (account, transaction, etc)? Or should I create a "viewAccount" scope, a "viewTransaction" scope, etc?

    Scopes represent a set of rights at a protected resource. In your case, you have 2 resources: account and transaction, so I would lean towards the second approach.

    In the long run, having a global view scope associated with all your resources (e.g. account, transaction, customer, settlement...) makes authorization difficult to both manage and adapt to security requirement changes.

    Here are a few examples that you can check out to get a feel for design

    Do note though - I am not claiming that you shouldn't share scopes across resources. Matter of fact, Keycloak allows this for resources with the same type. You could for instance need both viewAccount and viewTransaction scope to read a transaction under a given account (after all you might need access to the account to view transactions). Your requirements and standards will heavily influence your design.

    For each practical combination of resource and scope, is it usual practice to create a permission?

    Apologies, I don't fully understand the question so I'll be a bit broad. In order to grant/deny access to a resource, you need to:

    • Define your policies
    • Define your permissions
    • Apply your policies to your permissions
    • Associate your permissions to a scope or resource (or both)

    for policy enforcement to take effect. See Authorization Process.

    How you go about setting all this up is entirely up to you. You could for instance:

    • Define individual policies, and tie each policy under the appropriate permission.

    • Better yet, define individual policies, then group all your related policies under an aggregated policy (a policy of policies) and then associate that aggregated policy with the scope-based permission. You could have that scoped-based permission apply to both the resource and all its associated scope.

    • Or, you could further break apart your permissions by leveraging the two separate types. You could create permissions solely for your resources via the resource-based permission type, and separately associate other permissions solely with a scope via the scope-based permission type.

    You have options.

    If there are multiple permissions matching a given resource/scope, what does Keycloak do?

    This depends on

    1. The resource server's Decision Strategy
    2. Each permission's Decision Strategy
    3. Each policy's Logic value.

    The Logic value is similar with Java's ! operator. It can either be Positive or Negative. When the Logic is Positive, the policy's final evaluation remains unchanged. When its Negative, the final result is negated (e.g. if a policy evaluates to false and its Logic is Negative, then it will be true). To keep things simple, let's assume that the Logic is always set to Positive.

    The Decision Strategy is what we really want to tackle. The Decision Strategy can either be Unanimous or Affirmative. From the docs,

    Decision Strategy

    This configurations changes how the policy evaluation engine decides whether or not a resource or scope should be granted based on the outcome from all evaluated permissions. Affirmative means that at least one permission must evaluate to a positive decision in order grant access to a resource and its scopes. Unanimous means that all permissions must evaluate to a positive decision in order for the final decision to be also positive. As an example, if two permissions for a same resource or scope are in conflict (one of them is granting access and the other is denying access), the permission to the resource or scope will be granted if the chosen strategy is Affirmative. Otherwise, a single deny from any permission will also deny access to the resource or scope.

    Let's use an example to better understand the above. Suppose you have a resource with 2 permissions and someone is trying to access that resource (remember, the Logic is Positive for all policies). Now:

    1. Permission One has a Decision Strategy set to Affirmative. It also has 3 policies where they each evaluate to:
      • true
      • false
      • false

    Since one of the policies is set to true, Permission One is set to true (Affirmative - only 1 needs to be true).

    1. Permission Two has a Decision Strategy set to Unanimous with 2 policies:
      • true
      • false

    In this case Permission Two is false since one policy is false (Unanimous - they all need to be true).

    1. Now comes the final evaluation. If the resource server's Decision Strategy is set to Affirmative, access to that resource would be granted because Permission One is true. If on the other hand, the resource server's Decision Strategy is set to Unanimous, access would be denied.

    See:

    We'll keep revisiting this. I explain how to set the resource sever's Decision Strategy in Part II.

    so for example I could have permission to access "accounts" and permission for "view" scope, so therefore I would have permission to view accounts?

    The short answer is yes. Now, let's expand on this a bit :)

    If you have the following scenario:

    1. Resource server's Decision Strategy set to Unanimous or Affirmative
    2. Permission to access the account/{id} resource is true
    3. Permission to access the view scope is true

    You will be granted access to view the account.

    • true + true is equal to true under the Affirmative or Unanimous Decision Strategy.

    Now if you have this

    1. Resource server's Decision Strategy set to Affirmative
    2. Permission to access the account/{id} resource is true
    3. Permission to access the view scope is false

    You will also be granted access to view the account.

    • true + false is true under the Affirmative strategy.

    The point here is that access to a given resource also depends on your setup so be careful as you may not want the second scenario.

    But am I right that this means I need a policy for each of the legacy groups that a user could belong to?

    I'm not sure how Keycloak behaved 2 years ago, but you can specify a Group-Based policy and simply add all your groups under that policy. You certainly do not need to create one policy per group.

    For example, if I have a "helpdesk" role, then I need a "helpdesk membership" policy, which I could then add to the "viewAccount" permission. Is this correct?

    Pretty much. There are many ways you can set this up. For instance, you can:

    1. Create your resource (e.g. /account/{id}) and associate it with the account:view scope.
    2. create a Role-Based Policy and add the helpdesk role under that policy
    3. Create a Scope-Based permission called viewAccount and tie it with scope, resource and policy

    We'll set up something similar in Part II.

    Part II

    Keycloak has a neat little tool which allows you test all your policies. Better yet, you actually do not need to spin up another application server and deploy a separate app for this to work.

    Here's the scenario that we'll set up:

    1. We'll create a new realm called stackoverflow-demo
    2. We'll create a bank-api client under that realm
    3. We will define a resource called /account/{id} for that client
    4. The account/{id} will have the account:view scope
    5. We'll create a user called bob under the new realm
    6. We'll also create three roles: bank_teller, account_owner and user
      • We will not associate bob with any roles. This is not needed right now.
    7. We'll set up the following two Role-Based policies:
      • bank_teller and account_owner have access to the /account/{id} resource
      • account_owner has access to the account:view scope
      • user does not have access to the resource or scope
    8. We'll play around with the Evaluate tool to see how access can be granted or denied.

    Do forgive me, this example is unrealistic but I'm not familiar with the banking sector :)

    Keycloak setup

    Download and run Keycloak

    cd tmp
    wget https://downloads.jboss.org/keycloak/8.0.0/keycloak-8.0.0.zip 
    unzip keycloak-8.0.0.zip
    cd keycloak-8.0.0/bin
    ./standalone.sh 
    

    Create initial admin user

    1. Go to http://localhost:8080/auth
    2. Click on the Administration Console link
    3. Create the admin user and login

    Visit Getting Started for more information. For our purposes, the above is enough.

    Setting up the stage

    Create a new realm

    1. Hover your mouse around the master realm and click on the Add Realm button.
    2. Enter stackoverflow-demo as the name.
    3. Click on Create.
    4. The top left should now say stackoverflow-demo instead of the master realm.

    See Creating a New Realm

    Create a new user

    1. Click on the Users link on the left
    2. Click on the Add User button
    3. Enter the username (e.g. bob)
    4. Ensure that User Enabled is turned on
    5. Click Save

    See Creating a New User

    Create new roles

    1. Click on the Roles link
    2. Click on Add Role
    3. Add the following roles: bank_teller, account_owner and user

    Again, do not associate your user with the roles. For our purposes, this is not needed.

    See Roles

    Create a client

    1. Click on the Clients link
    2. Click on Create
    3. Enter bank-api for the Client ID
    4. For the Root URL enter http://127.0.0.1:8080/bank-api
    5. Click on Save
    6. Ensure that Client Protocol is openid-connect
    7. Change the Access Type to confidential
    8. Change Authorization Enabled to On
    9. Scroll down and hit Save. A new Authorization tab should appear at the top.
    10. Click on the Authorization tab and then Settings
    11. Ensure that the Decision Strategy is set to Unanimous
      • This is the resource server's Decision Strategy

    See:

    Create Custom Scopes

    1. Click on the Authorization tab
    2. Click on Authorization Scopes > Create to bring up Add Scope page
    3. Enter account:view in the name and hit enter.

    Create "View Account Resource"

    1. Click on Authorization link above
    2. Click on Resources
    3. Click on Create
    4. Enter View Account Resource for both the Name and Display name
    5. Enter account/{id} for the URI
    6. Enter account:view in the Scopes textbox
    7. Click Save

    See Creating Resources

    Create your policies

    1. Again under the Authorization tab, click on Policies
    2. Select Role from the the Create Policy dropdown
    3. In the Name section, type Only Bank Teller and Account Owner Policy
    4. Under Realm Roles select both the bank_teller and account_owner role
    5. Ensure that Logic is set to Positive
    6. Click Save
    7. Click on the Policies link
    8. Select Role again from the Create Policy dropdown.
    9. This time use Only Account Owner Policy for the Name
    10. Under Realm Roles select account_owner
    11. Ensure that Logic is set to Positive
    12. Click Save
    13. Click on the Policies link at the top, you should now see your newly created policies.

    See Role-Based Policy

    Do note that Keycloak has much more powerful policies. See Managing Policies

    Create Resource-Based Permission

    1. Again under the Authorization tab, click on Permissions
    2. Select Resource-Based
    3. Type View Account Resource Permission for the Name
    4. Under Resources type View Account Resource Permission
    5. Under Apply Policy select Only Bank Teller and Account Owner Policy
    6. Ensure that the Decision Strategy is set to Unanimous
    7. Click Save

    See Create Resource-Based Permissions

    Phew...

    Evaluating the Resource-Based permission

    1. Again under the Authorization tab, select Evaluate
    2. Under User enter bob
    3. Under Roles select user
      • This is where we will associate our user with our created roles.
    4. Under Resources select View Account Resource and click Add
    5. Click on Evaluate.
    6. Expand the View Account Resource with scopes [account:view] to see the results and you should see DENY.

    1. This makes sense because we only allow two roles access to that resource via the Only Bank Teller and Account Owner Policy. Let's test this to make sure this is true!
    2. Click on the Back link right above the evaluation result
    3. Change bob's role to account_owner and click on Evaluate. You should now see the result as PERMIT. Same deal if you go back and change the role to bank_teller

    See Evaluating and Testing Policies

    Create Scope-Based Permission

    1. Go back to the Permissions section
    2. Select Scope-Based this time under the Create Permission dropdown.
    3. Under Name, enter View Account Scope Permission
    4. Under Scopes, enter account:view
    5. Under Apply Policy, enter Only Account Owner Policy
    6. Ensure that the Decision Strategy is set to Unanimous
    7. Click Save

    See Creating Scope-Based Permissions

    Second test run

    Evaluating our new changes

    1. Go back to the Authorization section
    2. Click on Evaluate
    3. User should be bob
    4. Roles should be bank_teller
    5. Resources should be View Account Resource and click Add
    6. Click on Evaluate and we should get DENY.
      • Again this should come as no surprise as the bank_teller has access to the resource but not the scope. Here one permission evaluates to true, and the other to false. Given that the resource server's Decision Strategy is set to Unanimous, the final decision is DENY.
    7. Click on Settings under the Authorization tab, and change the Decision Strategy to Affirmative and go back to steps 1-6 again. This time, the final result should be PERMIT (one permission is true, so final decision is true).
    8. For the sake of completeness, turn the resource server's Decision Strategy back to Unanimous. Again, go back to steps 1 through 6 but this time, set the role as account_owner. This time, the final result is again PERMIT which makes sense, given that the account_owner has access to both the resource and scope.

    Neat :) Hope this helps.

    这篇关于keycloak 中的资源、范围、权限和策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆