Chuyển đến nội dung chính

レッスン 5: 役割、権限、およびアクセス制御

レルム ロール、クライアント ロール、複合ロール、ユーザーとグループのロール マッピング、デフォルト ロール、サービス アカウント ロール。詳細な管理権限 V2、レルム管理委任、リソース固有の権限、ポリシー、権限評価。

Keycloak RBAC & Fine-grained Permissions

KeycloakのRBACおよびファイングレイン管理者権限V2モデル

1. Keycloakの役割の概要

Keycloak のロールは、アクセスを分散化するための主要なメカニズムです。アプリケーションは、ユーザーのロールを (トークン内のクレームを通じて) チェックして、ユーザーに何が許可されているかを決定します。 Keycloakは2種類のロールをサポートしています。レルムの役割そしてクライアントの役割.

レルムの役割とクライアントの役割

特性レルムの役割クライアントの役割
範囲領域全体特定のクライアントのみ
ユースケース一般的な役割 (管理者、ユーザー、マネージャー)アプリケーション固有の役割 (編集者、閲覧者)
名前空間レルム内でユニーククライアント内で一意
トークンの請求realm_access.rolesresource_access.{client}.roles

2. レルムの役割

2.1 デフォルトのレルムの役割

Keycloak では、次のような多数のレルム ロールが利用可能になります。

  • デフォルトの役割-{レルム}— 複合ロールには、新規ユーザーのデフォルトのロールが含まれています

  • オフラインアクセス— オフライン トークンを取得できます (長期トークン更新)。

  • uma_authorization— UMA (ユーザー管理アクセス) の使用を許可します。

2.2 レルムロールの作成

管理コンソール経由:

  1. クリックレルムの役割サイドバーにある

  2. クリックロールの作成

  3. 入力:

    • 役割名: 管理者。管理者
    • 説明: 完全な管理者アクセス
  4. クリック保存

管理者 CLI 経由:

# Tạo realm roles
bin/kcadm.sh create roles -r my-company -s name=admin -s description="Full administrator access"
bin/kcadm.sh create roles -r my-company -s name=manager -s description="Manager with limited admin access"
bin/kcadm.sh create roles -r my-company -s name=user -s description="Regular user"
bin/kcadm.sh create roles -r my-company -s name=viewer -s description="Read-only access"

Xem danh sách realm roles

bin/kcadm.sh get roles -r my-company --fields name,description

REST API経由:

# Tạo realm role
curl -s -X POST \
  "http://localhost:8080/admin/realms/my-company/roles" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "admin",
    "description": "Full administrator access",
    "composite": false
  }'

Lấy danh sách realm roles

curl -s -X GET
"http://localhost:8080/admin/realms/my-company/roles"
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.[].name'

3. クライアントの役割

クライアント ロールは、アプリケーションに独自のロールが必要な場合に使用されます。たとえば、CMS アプリケーションにはロールがあります。エディタ, 著者, 査読者HR アプリケーションの役割とは異なります。

3.1 クライアントロールの作成

管理コンソール経由:

  1. 入力クライアント→ クライアントを選択 (例:私のウェブアプリ)

  2. タブ役割

  3. クリックロールの作成

  4. 名前と説明を入力してください

CLI 経由:

# Lấy client ID
CLIENT_UUID=$(bin/kcadm.sh get clients -r my-company -q clientId=my-web-app --fields id --format csv --noquotes)

Tạo client roles

bin/kcadm.sh create clients/$CLIENT_UUID/roles -r my-company
-s name=editor -s description="Can create and edit content"

bin/kcadm.sh create clients/$CLIENT_UUID/roles -r my-company
-s name=author -s description="Can create content"

bin/kcadm.sh create clients/$CLIENT_UUID/roles -r my-company
-s name=reviewer -s description="Can review and approve content"

bin/kcadm.sh create clients/$CLIENT_UUID/roles -r my-company
-s name=content-admin -s description="Full content management"

Xem client roles

bin/kcadm.sh get clients/$CLIENT_UUID/roles -r my-company --fields name,description

REST API経由:

curl -s -X POST \
  "http://localhost:8080/admin/realms/my-company/clients/$CLIENT_UUID/roles" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "editor",
    "description": "Can create and edit content"
  }'

3.2 トークンにおけるクライアントの役割

クライアント ロールはクレームの下のアクセス トークンに表示されますリソースアクセス:

{
  "realm_access": {
    "roles": ["user", "offline_access"]
  },
  "resource_access": {
    "my-web-app": {
      "roles": ["editor", "author"]
    },
    "my-api": {
      "roles": ["read", "write"]
    },
    "account": {
      "roles": ["manage-account", "view-profile"]
    }
  }
}

4. 複合役割

複合ロールは、1 つ以上の子ロール (レルム ロールおよび/またはクライアント ロール) を含むロールです。ユーザーに複合ロールが割り当てられると、そのユーザーは自動的にすべての子のロールを持ちます。

4.1 複合ロールの作成

管理コンソール経由:

  1. 入力レルムの役割→ 役割を選択 (例:管理者。管理者)

  2. タブアクション → 関連する役割を追加する

  3. 追加するロールを選択します (レルム ロールおよび/またはクライアント ロール)

  4. クリック割り当てる

CLI 経由:

# Tạo composite role: "manager" chứa "user" và "viewer"
bin/kcadm.sh add-roles \
  -r my-company \
  --rname manager \
  --rolename user \
  --rolename viewer

Thêm client roles vào composite role

bin/kcadm.sh add-roles
-r my-company
--rname manager
--cclientid my-web-app
--rolename editor
--rolename reviewer

階層の例:

admin (composite)
├── manager (composite)
│   ├── user (realm role)
│   ├── viewer (realm role)
│   ├── my-web-app/editor (client role)
│   └── my-web-app/reviewer (client role)
├── my-web-app/content-admin (client role)
└── account/manage-account (client role)

注記:ユーザーにロールが割り当てられるとき管理者。管理者、ユーザーはそれを持ちます全てツリー階層内の役割:管理者。管理者, マネージャー, ユーザー.ユーザー, 視聴者。ビューア, エディタ, 査読者, コンテンツ管理者, アカウントの管理.

4.2 「複合ロール」を参照

# Xem roles con của composite role
bin/kcadm.sh get-roles -r my-company --rname admin --effective

REST API

curl -s -X GET
"http://localhost:8080/admin/realms/my-company/roles/admin/composites"
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.[].name'

5. 役割のマッピング

5.1 ユーザーへの役割の割り当て

管理コンソール経由:

  1. 入力ユーザー→ ユーザーを選択

  2. タブ役割のマッピング

  3. クリック役割の割り当て

  4. レルムロールを選択するか、クライアントでフィルターしてクライアントロールを選択します

  5. クリック割り当てる

CLI 経由:

# Gán realm roles cho user
bin/kcadm.sh add-roles \
  -r my-company \
  --uusername john.doe \
  --rolename admin

Gán client roles cho user

bin/kcadm.sh add-roles
-r my-company
--uusername john.doe
--cclientid my-web-app
--rolename editor

Xem roles của user (bao gồm effective roles từ composite và groups)

bin/kcadm.sh get-roles
-r my-company
--uusername john.doe
--effective

REST API経由:

# Lấy role representation
ROLE_ID=$(curl -s -X GET \
  "http://localhost:8080/admin/realms/my-company/roles/admin" \
  -H "Authorization: Bearer $ACCESS_TOKEN" | jq -r '.id')

ROLE_NAME=$(curl -s -X GET
"http://localhost:8080/admin/realms/my-company/roles/admin"
-H "Authorization: Bearer $ACCESS_TOKEN" | jq -r '.name')

Gán realm role cho user

curl -s -X POST
"http://localhost:8080/admin/realms/my-company/users/$USER_ID/role-mappings/realm"
-H "Authorization: Bearer $ACCESS_TOKEN"
-H "Content-Type: application/json"
-d "[$(curl -s -X GET
"http://localhost:8080/admin/realms/my-company/roles/admin"
-H "Authorization: Bearer $ACCESS_TOKEN")]"

5.2 グループへの役割の割り当て

グループに役割を割り当てるときは、メンバー全員グループ (およびサブグループ) のメンバーがその役割を継承します。

# Qua CLI
bin/kcadm.sh add-roles \
  -r my-company \
  --gname Engineering \
  --rolename user

bin/kcadm.sh add-roles \
  -r my-company \
  --gname Engineering \
  --cclientid my-web-app \
  --rolename viewer

# Qua REST API
curl -s -X POST \
  "http://localhost:8080/admin/realms/my-company/groups/$GROUP_ID/role-mappings/realm" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d "[$(curl -s -X GET \
    "http://localhost:8080/admin/realms/my-company/roles/user" \
    -H "Authorization: Bearer $ACCESS_TOKEN")]"

5.3 効果的な役割

ユーザーの実効ロール = 直接割り当てられたロール + グループから継承されたロール + 複合ロールからのロール:

# Xem effective realm roles
curl -s -X GET \
  "http://localhost:8080/admin/realms/my-company/users/$USER_ID/role-mappings/realm/composite" \
  -H "Authorization: Bearer $ACCESS_TOKEN" | jq '.[].name'

Xem effective client roles

curl -s -X GET
"http://localhost:8080/admin/realms/my-company/users/$USER_ID/role-mappings/clients/$CLIENT_UUID/composite"
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.[].name'

6. デフォルトの役割

デフォルトのロールは、アカウントの作成時または登録時にすべての新規ユーザーに自動的に割り当てられます。

6.1 デフォルトの役割の構成

管理コンソール経由:

  1. 入力レルムの役割

  2. 役割を見つけるデフォルトの役割-{レルム}(例えば:デフォルトの役割 - 私の会社)

  3. 「役割」→「タブ」をクリックしますアクション → 関連する役割を追加する

  4. デフォルトとして設定したいロールを選択します

CLI 経由:

# Thêm role vào default roles
bin/kcadm.sh add-roles \
  -r my-company \
  --rname default-roles-my-company \
  --rolename user \
  --rolename offline_access

Thêm client role vào default roles

bin/kcadm.sh add-roles
-r my-company
--rname default-roles-my-company
--cclientid my-web-app
--rolename viewer

その後、新しく作成されたすべてのユーザーに自動的にロールが割り当てられます。ユーザー.ユーザー, オフラインアクセス, 私のウェブアプリ/ビューア.

7. サービスアカウントの役割

サービス アカウントはサービス間の通信 (マシン間) に使用されます。ユーザーの操作は必要ありません。

7.1 クライアントのサービスアカウントを有効にする

  1. 入力クライアント→ クライアントの選択または作成

  2. タブ設定:

    • クライアント認証: の上
    • サービスアカウントの役割: の上
    • 認可: オフ (認証サービスが必要な場合を除く)
  3. クリック保存

7.2 サービスアカウントへの役割の割り当て

# Qua Admin Console:
# Clients → chọn client → tab "Service account roles" → Assign role

Qua CLI - lấy service account user

SA_USER_ID=$(bin/kcadm.sh get clients/$CLIENT_UUID/service-account-user -r my-company --fields id --format csv --noquotes)

Gán realm roles

bin/kcadm.sh add-roles
-r my-company
--uid $SA_USER_ID
--rolename admin

Gán client roles (realm-management) cho API access

bin/kcadm.sh add-roles
-r my-company
--uid $SA_USER_ID
--cclientid realm-management
--rolename manage-users
--rolename view-users
--rolename manage-clients

7.3 サービスアカウントの使用

# Lấy access token cho service account (client credentials grant)
ACCESS_TOKEN=$(curl -s -X POST \
  "http://localhost:8080/realms/my-company/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=my-backend-service" \
  -d "client_secret=YOUR_CLIENT_SECRET" | jq -r '.access_token')

Sử dụng token để gọi API

curl -s -X GET
"http://localhost:8080/admin/realms/my-company/users"
-H "Authorization: Bearer $ACCESS_TOKEN" | jq '.[].username'

8. きめ細かい管理者権限 V2

きめ細かい管理権限 V2 (Keycloak 26 以降) により、生のレルム管理クライアント ロールを使用するだけでなく、管理コンソールで誰がどのリソースを管理できるかをきめ細かく制御できます。

8.1 詳細な管理者権限を有効にする

  1. 入力レルム設定 → 一般的な

  2. 探す管理者の権限→オンにするきめ細かい管理者権限 (V2)

  3. Keycloakはレルムに権限管理リソースを作成します

注記:これはKeycloak 26.xのプレビュー機能です。運用環境では、有効にする前に慎重に評価する必要があります。

8.2 リソースの権限

有効にすると、リソースの権限を作成できます。

ユーザーの権限:

許可説明する
ビュー。ビューユーザーのリストと詳細を表示する
管理ユーザーの作成、編集、削除
マップの役割ユーザーへの役割の割り当て/削除
グループメンバーシップの管理グループへのユーザーの追加/削除
なりすますユーザーになりすます

グループの権限:

許可説明する
ビュー。ビューグループを見る
管理グループの作成、編集、削除
ビューメンバーグループのメンバーを表示
メンバーの管理メンバーの追加/削除
メンバーシップの管理グループメンバーシップを管理する

クライアントの権限:

許可説明する
ビュー。ビュークライアントを見る
管理クライアントの作成、編集、削除
構成するクライアント設定を変更する
マップの役割クライアントロールの作成/割り当て

役割の権限:

許可説明する
ビュー。ビュー役割を参照
管理ロールの作成、編集、削除
マップロールユーザー/グループに役割を割り当てる

8.3 権限の作成

  1. 入力レルム設定 → 管理者権限

  2. リソース タイプ (ユーザー、グループ、クライアント、ロール) を選択します。

  3. 構成する必要がある権限をクリックします (例:管理ユーザー向け)

  4. もっと政策。政策誰がこの権限を持っているかを判断する

8.4 ポリシー

ポリシーは、アクセス許可を付与するための条件を定義します。 Keycloak V2 は次のポリシーをサポートします。

役割ベースのポリシー:

// Cho phép users có role "hr-admin" quản lý users
{
  "type": "role",
  "name": "HR Admin Policy",
  "description": "Users with hr-admin role",
  "roles": [
    {
      "id": "{role-id-of-hr-admin}",
      "required": true
    }
  ]
}

ユーザーベースのポリシー:

// Cho phép specific users
{
  "type": "user",
  "name": "Specific Admin Policy",
  "users": [
    "{user-id-of-admin-1}",
    "{user-id-of-admin-2}"
  ]
}

グループベースのポリシー:

// Cho phép members của group
{
  "type": "group",
  "name": "Admin Group Policy",
  "groups": [
    {
      "id": "{group-id-of-admins}",
      "extendChildren": true
    }
  ]
}

クライアントベースのポリシー:

// Cho phép specific clients (service accounts)
{
  "type": "client",
  "name": "Backend Service Policy",
  "clients": [
    "{client-id-of-backend-service}"
  ]
}

8.5 実践例: 人事管理者はユーザーのみを管理する

要件: ユーザーにはロールがあるhr-管理者ユーザーの表示と管理のみが許可され、クライアントやレルム設定の管理は許可されません。

  1. レルムロールの作成 hr-管理者:

    bin/kcadm.sh create roles -r my-company \
      -s name=hr-admin \
      -s description="HR Administrator - can manage users only"
  2. きめ細かい管理者権限 V2 を有効にする

  3. ロールベースのポリシーの作成与えるhr-管理者:

    • 「管理者権限」→「ポリシー」タブに移動します。
    • ポリシーの作成 → ロールベース
    • 名前: 「人事管理ポリシー」
    • 役割を選択してください:hr-管理者
  4. ユーザー権限にポリシーを割り当てる:

    • ユーザー → 許可ビュー。ビュー→ ポリシー「人事管理ポリシー」を追加
    • ユーザー → 許可管理→ ポリシー「人事管理ポリシー」を追加
  5. ユーザーに役割を割り当てる:

    bin/kcadm.sh add-roles -r my-company \
      --uusername hr-manager \
      --rolename hr-admin

現在のユーザー人事マネージャー管理コンソールにログインしてメニューのみを表示できますユーザー.

8.6 許可の評価

[評価] タブを使用して権限をテストできます。

  1. 入力管理者権限 → 評価する

  2. テストするユーザーまたはクライアントを選択します

  3. リソースの種類と権限を選択します

  4. クリック評価する結果を確認するには (許可または拒否)

9. 専用レルム管理コンソール

Keycloak を使用すると、レルムごとに個別の管理者アカウントを作成できます。マスター レルムにアクセスする必要はありません。

9.1 レルム管理者の作成

# Tạo user trong realm
bin/kcadm.sh create users -r my-company \
  -s username=realm-admin \
  -s [email protected] \
  -s enabled=true \
  -s emailVerified=true

bin/kcadm.sh set-password -r my-company
--username realm-admin
--new-password "RealmAdmin@123"

Gán realm-management client roles

bin/kcadm.sh add-roles -r my-company
--uusername realm-admin
--cclientid realm-management
--rolename realm-admin

9.2 レルム管理クライアントの役割

クライアントレルム管理管理者権限を制御するために利用可能な役割:

役割説明する
レルム管理者レルムの完全な管理者アクセス
ユーザーの管理ユーザーを管理する
ユーザーの表示ユーザーを見る
クライアントの管理クライアントの管理
ビュークライアントクライアントを見る
レルムの管理レルム設定を管理する
ビューレルムレルム設定を参照
アイデンティティプロバイダーの管理ID プロバイダーの管理
イベントの管理イベントの管理
管理-認可認可管理
なりすましユーザーになりすます
クエリユーザーユーザーを検索する
クエリグループグループを検索する
クエリクライアントクライアントを検索する
クエリレルムレルムの検索

例: ユーザーとグループのみを管理する制限付き管理者を作成します。

bin/kcadm.sh add-roles -r my-company \
  --uusername limited-admin \
  --cclientid realm-management \
  --rolename manage-users \
  --rolename view-users \
  --rolename query-users \
  --rolename query-groups

10. アプリケーションでロールを使用する

10.1 アクセストークンからロールを確認する

デコードされたアクセス トークンには次の役割が含まれています。

{
  "sub": "user-uuid",
  "realm_access": {
    "roles": [
      "admin",
      "manager",
      "user",
      "default-roles-my-company",
      "offline_access",
      "uma_authorization"
    ]
  },
  "resource_access": {
    "my-web-app": {
      "roles": [
        "editor",
        "content-admin"
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  }
}

10.2 Spring Boot の例

// SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/api/admin/**").hasRole("admin")
            .requestMatchers("/api/content/**").hasRole("editor")
            .requestMatchers("/api/public/**").permitAll()
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer(oauth2 -> oauth2
            .jwt(jwt -> jwt
                .jwtAuthenticationConverter(jwtAuthenticationConverter())
            )
        );
    return http.build();
}

@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtGrantedAuthoritiesConverter converter = new JwtGrantedAuthoritiesConverter();
    converter.setAuthoritiesClaimName("realm_access.roles");
    converter.setAuthorityPrefix("ROLE_");
    
    JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
    jwtConverter.setJwtGrantedAuthoritiesConverter(converter);
    return jwtConverter;
}

}

10.3 Node.jsの例(Express)

// middleware/auth.js
const jwt = require('jsonwebtoken');

function hasRealmRole(role) { return (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ error: 'No token provided' });

try {
  const decoded = jwt.decode(token);
  const roles = decoded.realm_access?.roles || [];
  
  if (roles.includes(role)) {
    req.user = decoded;
    next();
  } else {
    res.status(403).json({ error: 'Insufficient permissions' });
  }
} catch (err) {
  res.status(401).json({ error: 'Invalid token' });
}

}; }

function hasClientRole(clientId, role) { return (req, res, next) => { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ error: 'No token provided' });

try {
  const decoded = jwt.decode(token);
  const roles = decoded.resource_access?.[clientId]?.roles || [];
  
  if (roles.includes(role)) {
    req.user = decoded;
    next();
  } else {
    res.status(403).json({ error: 'Insufficient permissions' });
  }
} catch (err) {
  res.status(401).json({ error: 'Invalid token' });
}

}; }

// Sử dụng app.get('/api/admin/users', hasRealmRole('admin'), (req, res) => { // Only admin can access });

app.post('/api/content', hasClientRole('my-web-app', 'editor'), (req, res) => { // Only editors can create content });

11. 練習問題

  1. レルムロールの作成: スーパー管理者, マネージャー, スタッフ, 視聴者。ビューア

  2. クライアントロールの作成クライアントのために私のウェブアプリ: コンテンツエディター, コンテンツレビュアー, コンテンツ発行者

  3. 複合ロールの作成:

    • スーパー管理者含む:マネージャー+ すべてのクライアントの役割
    • マネージャー含む:スタッフ + コンテンツレビュアー
    • スタッフ含む:視聴者。ビューア + コンテンツエディター
  4. グループに役割を割り当てる:

    • グループエンジニアリング: レルムの役割スタッフ
    • グループエンジニアリング/バックエンド: クライアントの役割コンテンツエディター
  5. きめ細かい管理者権限 V2 を有効にするそして以下を作成します:

    • ロールベースのポリシーhr-管理者
    • ユーザーの表示/管理権限にポリシーを割り当てる
    • ロールを持つユーザーでテストするhr-管理者
  6. サービスアカウントの作成クライアントのために私のバックエンドサービス役割付きユーザーの管理, ユーザーの表示クライアント資格情報の付与を使用してテストします

12. まとめ

このレッスンでは、次のことを学びました。

  • 区別するレルムの役割そしてクライアントの役割

  • 作成する複合役割分散型階層構造

  • 役割のマッピングユーザーおよびグループ向け (直接およびレガシー)

  • 構成デフォルトの役割新規ユーザー向け

  • 使用サービスアカウントの役割マシンツーマシン通信用

  • きめ細かい管理者権限 V2ポリシー付き (ロールベース、ユーザーベース、グループベース、クライアントベース)

  • 作成する専用レルム管理者制限された権限で

  • アプリケーション内のロールを確認する (Spring Boot、Node.js)

次の記事で手順を説明しますクライアント、クライアント スコープ、および OpenID Connectキークロークで。