keycloakのリソース、スコープ、権限、およびポリシー


91

Keycloakの認証システムを使用して、かなり単純なロールベースのアクセス制御システムを作成したいと思います。Keycloakが置き換えるシステムでは、1つ以上の「グループ」のメンバーである「ユーザー」を作成できます。このレガシーシステムでは、ユーザーには、グループメンバーシップ(グループにアクセス許可が割り当てられる)またはユーザーへのアクセス許可の直接付与のいずれかを通じて、約250の「機能」のそれぞれにアクセスするための「アクセス許可」が与えられます。

レガシーシステムをkeycloak認証にマッピングしたいと思います。

既存のシステムの各「機能」をキークロークリソースとキークロークスコープのセットにマッピングするのは簡単なはずです。たとえば、「viewAccount」機能は明らかに「account」リソースと「view」スコープにマップされます。「viewTransaction」は「transaction」リソースにマップされます...しかし、「view」スコープを1つだけ作成し、それを複数のリソース(アカウント、トランザクションなど)で使用するのがベストプラクティスですか?または、「viewAccount」スコープ、「viewTransaction」スコープなどを作成する必要がありますか?

同様に、私は許可について少し混乱しています。リソースとスコープの実際的な組み合わせごとに、権限を作成するのが通常の方法ですか?特定のリソース/スコープに一致する複数のアクセス許可がある場合、Keycloakは何をしますか?Keycloakの目的は、リソースとスコープに対する権限のマトリックスを構成できるようにすることだと思います。たとえば、「アカウント」にアクセスする権限と「表示」スコープの権限を持つことができるので、権限があります。アカウントを表示するには?

このすべての結果として、私の古い「viewAccount」機能が、「View」スコープと「viewAccount」権限を持つ「Account」リソースを作成することになり、元の場所に戻るように見えるので、私は尋ねます。それが正しければ、どちらでも構いません。

最後に、viewAccountを適用するかどうかを決定する一連のポリシーが明らかに必要です。しかし、これは、ユーザーが属することができるレガシーグループごとにポリシーが必要であることを意味するのは正しいですか?たとえば、「ヘルプデスク」ロールがある場合は、「ヘルプデスクメンバーシップ」ポリシーが必要です。これを「viewAccount」権限に追加できます。これは正しいです?

ありがとう、

マーク


27
Keycloakはかなり成熟した非常に有能なシステムのように見えますが、質問が非常に多く、回答が非常に少ないように見えるため、実際に何ができるのかは謎のままです。私は文字通りあなたの投稿のすべての質問を自問していて、答えを見つけることができません。なぜそこに良いチュートリアルがないのですか?誰も実際にこのようなものを使用していませんか?それとも、誰もそれについて書くことを気にしませんか?
Stijn de Witt 2017

3
Keycloakは、私の実際の問題に関連付けるのが非常に困難であった承認を除いて、(これまでのところ)本番環境で非常にうまく機能しています。しかし、私は同意します。KeycloakがOIDCを実行する方法については多くのドキュメントがありますが、OAuthとOIDCを知っているという一般的な仮定もあります。OIDCをまだ知らない場合、Keycloakをアプリケーションの問題に関連付けるのは難しいですが、私にとってKeycloakはOIDCの紹介であり、ちょっとしたキャッチ22です(Picketlink / Picketboxはさらにひどいものでした!)。ダウンロードして遊んでみるのが一番良かったです。
Doctor Eval 2017

7
これらのコメント、keycloakのドキュメント、ユースケースの問題に同意する
Olivier Refalo 2017

23
Keycloak開発者、この質問に注意してください!あなたのドキュメントはかなり良いですが、ここで提起された質問に対処するためのより多くのチュートリアルが必要です。また、古い学校のメーリングリストから、フォーラムや単なるStackoverflowなどのもう少しユーザーフレンドリーなものに移行することを検討することもできます。
GGGforce 2018年

5
遅い答えですが、あなたのすべての仮定は基本的に正しいです。ベストプラクティスについては、機能が非常に新しいため、わかりにくいと思います。kc開発者でさえ、現時点でベストプラクティスが何であるかを知っているかどうかはわかりません。
cen 2018

回答:


138

私は2年以上遅れていることを知っていますが、私が知っていることを共有し、将来の読者の苦痛を和らげることができればと思います。完全な透明性-私は決してKeycloak / OAuth / OIDCの専門家ではありません。私が知っているのは、主にドキュメント、本、古き良きYouTubeを読んだり、ツールをいじったりすることです。

この投稿は2つの部分で構成されます。

  1. 私はあなたのすべての質問に私の能力の及ぶ限りでは答えようとします
  2. このスレッドのコアコンセプトのいくつかをよりよく理解するために、別のアプリをデプロイする必要なしに、Keycloakでポリシー/スコープ/パーミッションを試す方法をすべて紹介します。ただし、これは主にすべてを開始することを目的としていることに注意してください。私はを使用していKeycloak 8.0.0ます。

パートI

始める前のいくつかの用語:

  • Keycloakでは、次の2種類の権限を作成できます。リソースベーススコープ
  • 簡単に言えば、 Resource-Based権限については、リソースに直接適用します
  • 以下のためScoped-Basedの許可は、あなたのスコープ(複数可)または範囲(複数可)に適用し、リソース。

1つの「ビュー」スコープを作成し、それを複数のリソース(アカウント、トランザクションなど)で使用することをお勧めしますか?または、「viewAccount」スコープ、「viewTransaction」スコープなどを作成する必要がありますか?

スコープは、保護されたリソースでの一連の権限を表します。あなたの場合、2つのリソースがあります。accounttransaction、なので、2番目のアプローチに傾倒します。

長期的には、グローバルたview(すべてのリソースに関連付けられている範囲を例えばaccounttransactioncustomersettlement...)の両方に困難な許可が管理し、セキュリティ要件の変化に適応することができます。

デザインの感触をつかむためにチェックアウトできるいくつかの例を次に示します。

ただし、注意してください-リソース間でスコープを共有するべきではないと主張しているわけではありません。実際のところ、Keycloak同じリソースに対してこれを許可しますtype。たとえば、viewAccountviewTransaction、特定のアカウントでトランザクションを読み取るには、スコープのが必要になる可能性があります(結局、トランザクションを表示するには、アカウントにアクセスする必要があるかもしれません)。要件と標準は、設計に大きく影響します。

リソースとスコープの実際的な組み合わせごとに、権限を作成するのが通常の方法ですか?

申し訳ありませんが、私は質問を完全に理解していないので、少し広範になります。へのアクセスを許可/拒否するにはresource、次のことを行う必要があります。

  • ポリシーを定義する
  • あなたの定義 権限を
  • ポリシーを権限に適用する
  • 権限をscopeまたはresource(または両方)に関連付けます

ポリシーの施行を有効にするため。承認プロセスを参照してください。

これらすべてをどのように設定するかは、完全にあなた次第です。たとえば、次のことができます。

  • 個々のポリシーを定義し、適切な許可の下で各ポリシーを結び付けます。

  • さらに良いことに、個々のポリシーを定義してから、関連するすべてのポリシーをaggregatedポリシー(ポリシーのポリシー)の下にグループ化し、その集約されたポリシーをscope-basedアクセス許可に関連付けます。あなたはそれを持つことができますscoped-based権限をリソースとそれに関連するすべてのスコープの両方に適用するます。

  • または、2つの別々のタイプを活用して、権限をさらに分解することもできます。resource-based権限タイプを介してリソースに対してのみ権限を作成し、他の権限をscope-based権限タイプを介してスコープのみに個別に関連付けることができます。

オプションがあります。

特定のリソース/スコープに一致する複数のアクセス許可がある場合、Keycloakは何をしますか?

これは

  1. リソースサーバーの Decision Strategy
  2. 各許可の Decision Strategy
  3. 各ポリシーのLogic値。

Logic値は、Javaのと似ている!事業者。PositiveまたはのいずれかNegativeです。ときLogicPositive、政策の最終的な評価は変わりません。そのNegative場合、最終結果は否定されます(たとえば、ポリシーがfalseと評価され、それLogicNegativeである場合、それは否定されますtrue)。物事を単純にするために、Logicが常にに設定されていると仮定しましょうPositive

それDecision Strategyが私たちが本当に取り組みたいことです。はまたDecision StrategyはのいずれUnanimousAffirmativeです。ドキュメントから、

意思決定戦略

この構成により、評価されたすべてのアクセス許可の結果に基づいて、リソースまたはスコープを付与するかどうかをポリシー評価エンジンが決定する方法が変更されます。肯定的とは、リソースとそのスコープへのアクセスを許可するために、少なくとも1つの許可が肯定的な決定に評価される必要があることを意味します。全会一致とは、最終決定も肯定的であるためには、すべての許可が肯定的決定に評価される必要があることを意味します。例として、同じリソースまたはスコープに対する2つのアクセス許可が競合している場合(一方がアクセスを許可し、もう一方がアクセスを拒否している)、選択した戦略が肯定的であれば、リソースまたはスコープへのアクセス許可が付与されます。それ以外の場合、アクセス許可を1回拒否すると、リソースまたはスコープへのアクセスも拒否されます。

上記をよりよく理解するために例を使用してみましょう。2つの権限を持つリソースがあり、誰かがそのリソースにアクセスしようとしているとします(これLogicPositiveすべてのポリシーに適用されます)。今:

  1. Permission OneDecision Strategy設定されていAffirmativeます。また、それぞれが評価する3つのポリシーがあります。
    • true
    • false
    • false

ポリシーの1つがに設定されているためtruePermission Oneはに設定されますtrue(肯定的-1つだけが必要ですtrue)。

  1. Permission Two持っているDecision StrategyにセットをUnanimous2つのポリシーを持ちます:
    • true
    • false

この場合Permission Twofalse、1つのポリシーが偽であるためです(全会一致-すべてが偽である必要がありますtrue)。

  1. これで最終評価が行われます。リソースサーバーDecision Strategyがに設定されている場合、はであるためAffirmative、そのリソースへのアクセスが許可されPermission Oneますtrue。一方、リソースサーバーDecision Strategyがに設定されているUnanimous場合、アクセスは拒否されます。

見る:

これを再検討し続けます。Decision Strategy パートIIでリソースサーバーを設定する方法を説明します。

たとえば、「アカウント」にアクセスする権限と「表示」スコープの権限を持つことができるので、アカウントを表示する権限がありますか?

簡単な答えはイエスです。さて、これを少し拡張してみましょう:)

次のシナリオがある場合:

  1. リソースサーバーのDecision Strategy設定UnanimousまたはAffirmative
  2. account/{id}リソースにアクセスするための権限はtrue
  3. viewスコープにアクセスする権限はtrue

アカウントを表示するためのアクセス権が付与されます。

  • true+trueに等しいtrueAffirmativeまたはUnanimous Decision Strategy

今あなたがこれを持っているなら

  1. リソースサーバーのDecision Strategy設定Affirmative
  2. account/{id}リソースにアクセスするための権限はtrue
  3. viewスコープにアクセスする権限はfalse

あなたはします、アカウントを表示するためのアクセスを許可すること。

  • true+falseは戦略のtrue下にありAffirmativeます。

ここでのポイントは、特定のリソースへのアクセスもセットアップに依存するため、2番目のシナリオが必要ない場合があるので注意してください。

しかし、これは、ユーザーが属することができるレガシーグループごとにポリシーが必要であることを意味するのは正しいですか?

Keycloakが2年前にどのように動作したかはわかりませんが、グループベースのポリシーを指定して、そのポリシーの下にすべてのグループを追加するだけで済みます。確かに、グループごとに1つのポリシーを作成する必要はありません。

たとえば、「ヘルプデスク」ロールがある場合は、「ヘルプデスクメンバーシップ」ポリシーが必要です。これを「viewAccount」権限に追加できます。これは正しいです?

かなり。これを設定する方法はたくさんあります。たとえば、次のことができます。

  1. リソース(例/account/{id})を作成し、account:viewスコープに関連付けます。
  2. 役割ベースのポリシーを作成し、helpdeskそのポリシーの下に役割を追加します
  3. 作成Scope-Basedと呼ばれる許可をviewAccountしてとそれを結ぶscoperesourcepolicy

パートIIでも同様の設定を行います。

パートII

Keycloakには、すべてのポリシーをテストできる小さなツールがあります。さらに良いことに、これを機能させるために、実際には別のアプリケーションサーバーを起動して別のアプリをデプロイする必要はありません。

設定するシナリオは次のとおりです。

  1. と呼ばれる新しいレルムを作成します stackoverflow-demo
  2. bank-apiその領域の下にクライアントを作成します
  3. /account/{id}そのクライアントに呼び出されるリソースを定義します
  4. account/{id}必要がありますaccount:viewスコープを
  5. bob新しいレルムの下に呼び出されるユーザーを作成します
  6. 我々はまた、3つの役割を作成します:bank_telleraccount_ownerおよびuser
    • 私たちはbobいかなる役割にも関連付けません。これは今は必要ありません。
  7. 次の2つのRole-Basedポリシーを設定します。
    • bank_telleraccount_ownerにアクセスしてい/account/{id}たリソースを
    • account_owneraccount:viewスコープにアクセスできます
    • user リソースまたはスコープにアクセスできません
  8. 私たちはで遊んでよEvaluate、アクセスが許可または拒否することができます方法を確認するためのツール。

私を許してください、この例は非現実的ですが、私は銀行セクターに精通していません:)

Keycloakのセットアップ

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 

初期管理者ユーザーを作成する

  1. に移動 http://localhost:8080/auth
  2. Administration Consoleリンクをクリックしてください
  3. 管理者ユーザーを作成してログインします

詳細については、「はじめに」をご覧ください。私たちの目的では、上記で十分です。

ステージのセットアップ

新しいレルムを作成する

  1. masterレルムの周りにマウスを置き、Add Realmボタンをクリックします。
  2. stackoverflow-demo名前として入力します。
  3. をクリックしCreateます。
  4. 左上にレルムのstackoverflow-demo代わりに言う必要がありmasterます。

新しいレルムの作成を参照してください

新しいユーザーを作成する

  1. Users左側のリンクをクリックしてください
  2. クリックしてAdd User、ボタン
  3. username(例bob)を入力します
  4. User Enabledオンになっていることを確認します
  5. クリック Save

新しいユーザーの作成を参照してください

新しい役割を作成する

  1. Rolesリンクをクリックしてください
  2. クリック Add Role
  3. 次の役割を追加しますbank_telleraccount_owneruser

繰り返しますが、ユーザーをロールに関連付けないでください。私たちの目的では、これは必要ありません。

役割を参照してください

クライアントを作成する

  1. Clientsリンクをクリックしてください
  2. クリック Create
  3. に入力bank-apiしてくださいClient ID
  4. 以下のためのRoot URL入力http://127.0.0.1:8080/bank-api
  5. クリック Save
  6. それClient Protocolopenid-connect
  7. に変更Access Typeしますconfidential
  8. 変更Authorization EnabledOn
  9. 下にスクロールして、を押しSaveます。新しいAuthorizationタブが上部に表示されます。
  10. AuthorizationタブをクリックしてからSettings
  11. Decision Strategyがに設定されていることを確認しますUnanimous
    • これはリソースサーバーの Decision Strategy

見る:

カスタムスコープを作成する

  1. Authorizationタブをクリックします
  2. Authorization Scopes>CreateをクリックしてAdd Scopeページを表示します
  3. account:view名前を入力してEnterキーを押します。

「アカウントリソースの表示」を作成する

  1. 上のAuthorizationリンクをクリックしてください
  2. クリック Resources
  3. クリック Create
  4. 入力View Account Resourceの両方のためにNameDisplay name
  5. に入力account/{id}してくださいURI
  6. テキストボックスに入力account:viewしますScopes
  7. クリック Save

リソースの作成を参照してください

ポリシーを作成する

  1. 再びAuthorizationタブの下で、をクリックしますPolicies
  2. ドロップダウンRoleから選択しますCreate Policy
  3. ではNameセクション、タイプOnly Bank Teller and Account Owner Policy
  4. 下のRealm Roles選択の両方bank_telleraccount_owner役割
  5. Logicがに設定されていることを確認しますPositive
  6. クリック Save
  7. Policiesリンクをクリックしてください
  8. ドロップダウンRoleからもう一度選択しCreate Policyます。
  9. 今回Only Account Owner PolicyName
  10. 下のRealm Roles選択account_owner
  11. Logicがに設定されていることを確認しますPositive
  12. クリック Save
  13. Policies上部のリンクをクリックすると、新しく作成したポリシーが表示されます。

ロールベースのポリシーを参照してください

Keycloakにははるかに強力なポリシーがあることに注意してください。ポリシーの管理を参照してください

リソースベースの権限を作成する

  1. 再びAuthorizationタブの下で、をクリックしますPermissions
  2. 選択する Resource-Based
  3. タイプView Account Resource PermissionについてName
  4. Resourcesタイプの下View Account Resource Permission
  5. 下のApply Policy選択Only Bank Teller and Account Owner Policy
  6. Decision Strategyがに設定されていることを確認しますUnanimous
  7. クリック Save

リソースベースの権限の作成を参照してください

ふぅ...

リソースベースの権限の評価

  1. 再びAuthorizationタブの下で、Evaluate
  2. User入力の下でbob
  3. 下のRoles選択user
    • ここで、ユーザーを作成したロールに関連付けます。
  4. 以下の下でResources選択View Account Resourceし、クリックAdd
  5. [評価]をクリックします。
  6. 展開View Account Resource with scopes [account:view]の結果を見て、あなたが表示されるはずですDENY

ここに画像の説明を入力してください

  1. これは、を介してそのリソースへのアクセスを2つのロールにのみ許可するため意味がありOnly Bank Teller and Account Owner Policyます。これをテストして、これが正しいことを確認しましょう!
  2. Back評価結果の真上にあるリンクをクリックしてください
  3. bobの役割をに変更しaccount_owner、をクリックしEvaluateます。結果はとして表示されPERMITます。戻って役割をに変更した場合も同じ取引bank_teller

ポリシーの評価とテストを参照してください

スコープベースの権限を作成する

  1. Permissionsセクションに戻る
  2. ドロップダウンでScope-Based今回を選択しCreate Permissionます。
  3. 下にNameView Account Scope Permission
  4. 下にScopesaccount:view
  5. 下にApply PolicyOnly Account Owner Policy
  6. Decision Strategyがに設定されていることを確認しますUnanimous
  7. クリック Save

スコープベースの権限の作成を参照してください

2回目のテスト実行

新しい変更の評価

  1. Authorizationセクションに戻る
  2. クリック Evaluate
  3. ユーザーは bob
  4. 役割は bank_teller
  5. リソースはView Account Resource、クリックする必要がありますAdd
  6. をクリックするEvaluateと、が表示されますDENY
    • 繰り返しbank_tellerますが、resourceこれはにアクセスできますが、にはアクセスできないので、当然のことscopeです。ここでは、一方の権限がtrueと評価され、もう一方の権限がfalseと評価されます。リソースサーバーDecision Strategyがに設定されているUnanimous場合、最終的な決定はDENYです。
  7. タブのSettings下をクリックしAuthorization、をに変更しDecision StrategyAffirmative、手順1〜6に戻ります。今回は、最終結果は次のようになりますPERMIT(1つの許可が真であるため、最終決定が真です)。
  8. 完全を期すために、リソースサーバーをにDecision Strategy戻しますUnanimous。繰り返しますが、手順1〜6に戻りますが、今回は役割をとして設定しaccount_ownerます。今回も、との両方にアクセスできることをPERMIT考えると、最終結果は理にかなってaccount_ownerいます。resourcescope

きちんとした:)これが役立つことを願っています。


1
@SANDEEPMACHIRAJUどういたしまして:)いい質問です!コメントを介して詳細な回答を提供するのに十分な文字はありませんが、トークンイントロスペクションエンドポイントを使用できます。これがすべてのエンドポイントのリストです。私が考えて、あなたも自分の使用することができます認可のクライアントを、私はそれを使用して任意の経験を持っていない
アンディ・

9
素晴らしい答えをありがとう。
マルクス

3
@JWoどういたしまして!Tbh、特別な理由はありません。誰もが始められるように、例をできるだけ単純に保ちました。私は経験から、ドキュメントは読むのに最もエキサイティングなものではないことを知っています。銀行APIへのアクセスを必要とする別のクライアントに関してはUser Management Access (UMA)、リソース所有者が保護されたリソースへのアクセスを要求側に許可できる場所を探しているようです(少なくとも私の解釈です)。
アンディ

3
あなたは間違いなく、すべてをまとめるのに時間を割いてくれて、世界をより良い場所にしています...あなたはこれらすべてについていくつかのブログ投稿を書くべきです!非常に便利な@ Andy
JoséCarlos20年

1
@アンディはすごい!すべてのAuthServicesドキュメントを要約し、共有していただきありがとうございます。あなたは多くの人々の勉強の多くの時間を節約しました!見えないものが一つだけあります。あなたは言ったaccount_owner has access to the account:view scope。その役割とその範囲の関係をどのように確立しますか?
共依存

5

Luaにはアダプターがなかったため、アダプターを使用せずに、純粋なHTTPメソッドを介して承認を強制しようとしていました。この回答が、非アダプターベースの方法を探している人々に役立つことを願っています。

アダプターをお探しの場合は、クイックスタートガイドから始めるのが最適です。特にスプリングブート認証の例

純粋なHTTPベースの実装の場合:

ステップ1:

Keycloak管理UIでポリシーと権限を定義します

ステップ2

どのHTTPパスがどのリソースに属しているか、および各パスに必要なスコープの内部マッピングを用意します。これは、構成ファイルに保存することもできます。特定のルートが呼び出されたら、Keycloakトークンエンドポイントを呼び出して、アクセストークンのクレームを検証します。

{
  "policy-enforcer": {
    "user-managed-access" : {},
    "enforcement-mode" : "ENFORCING"
    "paths": [
      {
        "path" : "/someUri/*",
        "methods" : [
          {
            "method": "GET",
            "scopes" : ["urn:app.com:scopes:view"]
          },
          {
            "method": "POST",
            "scopes" : ["urn:app.com:scopes:create"]
          }
        ]
      }
    ]
  }
}

アダプターを使用していて、パスまたはリソースを指定しない場合、アダプターはKeycloakからパスとリソースを内部的に検索します。

ステップ3:

トークンエンドポイントを使用して、権限を取得または評価します。あなたは使用することができますresponse_modeいずれかにパラメータを最終決定を得る(アクセスを提供するかどうか)、または全体のアクセス許可を取得します。

curl -X POST \
  http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \
  -H "Authorization: Bearer ${access_token}" \
  --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
  --data "permission=Resource A#Scope A"

許可要求がどの許可にもマップされない場合、403代わりにHTTPステータスコードが返されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.