KeycloakからAWSコンソールにSAML認証でサインイン

# はじめに
AWSコンソールに，KeycloakからSAMLでサインインできるようにする設定手順です（2023/11現在）。KeycloakをIdP，AWSコンソールをSPとしたSAML認証の設定を行います。
関連して，記事中で扱うXMLやMapperについて，別記事にまとめました。

https://qiita.com/gaichi/items/0fc75aa647ec72831f38



# 設定方法
## keycloakの立ち上げ

KeycloakはDockerhubの公式イメージで立ち上げます。バージョンは16.1.1でした。
```
$  docker run -d -p 18080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=Password --name keycloak jboss/keycloak
```

参考

https://qiita.com/cold-wisteria/items/557c0d9bd34b9d638f58

今回はDockerホストの18080番ポートで，TLSなしで起動します。DockerホストのIPアドレスは10.0.99.9です。

## AWSのSAML用メタデータを取得
https://signin.aws.amazon.com/static/saml-metadata.xml を取得してローカルに保存しておきます。

## keycloak設定その1
http\://DockerホストのIPアドレス:18080/にアクセスするとKeyCloakのログイン画面が表示されます。docker run実行時に指定した管理ユーザ(admin)とパスワード（password）でログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/930bd74b-5675-94a8-a7ed-3eddec265c5d.png)

ログイン後，client→Createをクリックします。clientでは連携先のSP（今回はAWSコンソール）を登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/5f862de1-05c0-55be-e457-12fdb6b435f7.png)


ImportのSelect fileをクリックし，AWSからダウンロードした[saml-metadata.xml](https://signin.aws.amazon.com/static/saml-metadata.xml)を登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/5d28cde5-a77a-d8e7-0a15-32092a6a90a6.png)

Client IDに「urn:amazon:webservices」が反映されたことを確認し，Saveをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/37efbbdb-39a8-43f7-7da7-30005a882827.png)


Client(urn:amazon:webservices)の設定画面に遷移するので，以下の3項目を入力してSaveをクリックします。
- RootURL：　http://keycloakホスト名orIPアドレス:18080
- BaseURL：　/auth/realms/master/protocol/saml/clients/aws-saml
- IDP Initiated SSO URL Name：　aws-saml
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/3463b681-89f6-7786-2972-4c8086c3a88f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/b78cfa51-fbc1-be33-872a-c230bcc8cea9.png)

Realm Settingに移動し，「SAML2.0 Identity Provider Metadata」を右クリックしてdescriptor.xmlをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/fde96612-7ba7-8738-642c-48eaf6f256eb.png)



## AWS IAM設定
AWSコンソールからIAMに移動し，IDプロバイダ→「プロバイダを追加」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/b01e28e9-dbeb-9119-f3ed-020230721ece.png)

プロバイダのタイプは「SAML」，プロバイダ名は任意（今回は「local-keycloak」），メタデータドキュメントはKeycloakから取得したdescriptor.xmlをインポートし，「プロバイダを追加」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/e1bd5de1-1867-3d53-6f7c-b6d65c118045.png)
これでKeycloakがIdPとして登録できました。

Keycloakユーザに対して割り当てるロールを作成します。
IDプロバイダ追加後の画面で「ロールの割り当て」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/dfa33b65-fb14-23dd-afaf-37205b79cf86.png)


「新しいロールを作成」を選択して次へ進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/9a16dec6-fd50-c979-f581-168b96bffda2.png)

「信頼されたエンティティタイプ」は「SAML2.0フェデレーション」，「SAML2.0ベースのプロバイダー」は前の手順で作成したIDプロバイダ名，「許可されるアクセス」はプログラムとAWSマネジメントコンソールへのアクセスを許可する」を選択して次へ進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/7e5ffa37-98c9-8583-fd3a-552e862babae.png)

ロールに許可するポリシーを検索・チェックし，次に進みます（今回はAdministratorAccessポリシーを許可します。複数のポリシー割り当ても可能です）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/870d7637-af4f-1dd0-9700-de7d5ccd9223.png)

ロール名を設定し（今回はTestRoleSamlKeycloak-Adminaccess），ロールの作成を完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/0947ee6a-73fd-6c63-c846-ceee10c22814.png)
なお，ロールを複数作成すると，KeycloakユーザのSAMLサインイン時にロールを選択させることができます。今回は追加でViewonlyのポリシーを割り当てたTestRoleSamlKeycloak-Viewonlyも作成しました。

IDプロバイダと，ロールのARNを控えておきます。控えたARNは，後でKeycloak側に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/555a95db-ce09-75bd-1814-ba2b6cd7437c.png)

AWSコンソール側の設定はこれで完了です。

## keycloak設定その2

再びKeycloakの設定です。AWS側のロールにあわせて，Keycloak側にもロールを作成します。
Client→Urn:amazon:webservices→Role→Add roleをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/238dc8fa-ab87-7384-25e6-6530a5e30d11.png)

Role Nameに先ほど控えたARNを，「ロールのARN,IDプロバイダのARN」のようにカンマで区切って入力し，Saveをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/4133b036-ec13-9885-77dc-92aadfcfc71f.png)
AWS側にロールを複数作成した場合には，同じ手順でKeycloak側にもロールを登録します。

ロールを二つ追加した後の画面です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/1351257d-a502-c537-fe2d-01b07854bb92.png)

ClientScopeのDefaultScopeを削除します。
Assigned Default Client scopesにあるRole_Listを選択し，Remove selectedをクリックします。Role_listがAvailavle Client Scopesに移動していればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/da02bafd-e533-a4d0-a816-5a87967d743f.png)

ScopeのFull Scope Allowedを，ONからOFFに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/159ac7df-f0d4-d561-ff51-75637bae8b86.png)

Mappersを設定します。まず，デフォルトで入っていたNameを全件削除します。
（全件削除がめんどくさい方は，最低限https\://aws.amazon.com/SAML/Attributes/RoleSessionNameとhttps\://aws.amazon.com/SAML/Attributes/Roleの2件を削除してください。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/d8d13796-4aa9-d5bf-78b7-d58e14d6e1f3.png)
デフォルトで入っていたMapperは，AWSからダウンロードしたSaml-metadata.xmlに入っていた情報です。必須はRoleSessionNameとRoleですが，初期状態ではkeycloak側の情報をうまくSAML Responseにわたせません。そのためこの二つはいったん消して設定し直します。

全件削除を確認したら，Createをクリックし新規のMapperを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/cac80d6a-b036-339b-0bc5-4617c6b2ce4f.png)
以下3つのMapperを新規作成します（Session Durationはオプションなので設定しなくてもOK）。似た名前の項目があるので注意して選択してください。
- Session Role（必須）
        Protcol:saml
        Name:Session Role
        Mapper Typ:Role list
        Role attribute name:https\://aws.amazon.com/SAML/Attributes/Role
        Friendly Name:Session Role
        SAML Attribute Name Format:Basic
        Single Role Attribute:ON
- Session Name（必須）
        Protcol:saml
        Name:Session Name
        Mapper Type:User Property
        Property:username
        Friendly Name:Session Name
        SAML Attribute Name:https\://aws.amazon.com/SAML/Attributes/RoleSessionName
        SAML Attribute Name Format:Basic
- Session Duration（オプション）
        Protcol:saml
        Name：Session Duration
        Mapper Type:Hardcoded attribute
        Friendly Name:Session Duration
        SAML Attribute Name:https\://aws.amazon.com/SAML/Attributes/SessionDuration
        SAML Attribute Name Format:Basic
        Attribute value:28800
        
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/a135fafe-5ebc-4982-3552-ea0a057bd986.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/931b451f-60e1-fe05-00d3-07bda08e9715.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/f890b46a-685b-5749-7b7c-64e0c3483142.png)

Mapperが登録されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/f86dd3d9-8ca4-86c6-0946-e0188d3c8d01.png)

keycloakに，AWSへのサインインを許可するグループを追加します。
Group→Newをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/4b487cf5-6720-efd1-c216-c08e47e85df7.png)

Nameにグループ名（ここではaws-ssoとします）を入力し，Saveをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/3b941f98-bf4d-35bf-137b-c27b85b7ce72.png)

作成したグループ（aws-sso）に，Roleを割り当てます。
Role Mappingをクリックし，ClientRolesでurn:amazon:webservicesを選択します。AvailableRolesにRoleが出てくるので必要なロールを選択し，Add selectedをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/55f6d850-1e7a-9a19-fd7c-aa06b5a7b344.png)

Assigned Rolesにロールが表示されていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/66e22814-3948-d5c0-3e1a-9495ef900791.png)

KeyCloakにユーザを作成します。
Users→Add Userをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/e5e62ded-8740-fa71-d751-126b04b1bb66.png)

usernameにユーザIDを入力し，Saveをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/1dbd1e84-7c76-e45e-acf2-2c753758cbed.png)

ユーザのパスワードを設定します。
ユーザのCredentialsタブでPasswordを入力し，Set Passwordをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/8dabfa2f-5322-5abf-1fdd-949e8fc8a843.png)
TempraryがONの場合，初回ログイン時にパスワードの変更を求められます。

ユーザをaws-ssoグループに参加させます。
ユーザのGroupタブで，AvailableGroupのaws-ssoを選択し，Joinをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/6cb7ba86-82e5-4cc9-855e-7ba4cb4d2a5c.png)
Group Membershipにaws-ssoが表示されていればOKです。

設定はこれで完了です。

# 動作確認
kaycloakのClientメニューで，usrn:amazon:webservicesのBase URLのURLがAWSコンソールへSSOログインするためのURLです。ただ，そのままクリックしてもエラーが表示されてしまいます。keycloakのadminユーザでログインしたままで，adminにはAWSにアクセスするロールの割当てがないからです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/a32f9a46-8aa2-c00a-5846-39c7d6ba72e3.png)
別のブラウザを起動するか，いったんkeycloakからサインアウトして，SSO用のURLにアクセスします。

Keycloakのサインイン画面が表示されるので，keycloakに設定したユーザID（aws-ssoグループに属するユーザ）のログイン情報を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/ee71b3a8-b1b4-fb96-c7c8-af7afd151936.png)

ロールの選択画面がでるので，使いたいロールを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/04706980-04e4-be87-9688-9f0dfe64bc94.png)

サインインに成功すると，右上のユーザ名の箇所に，ロール名とKeycloak側のユーザ名が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/8e3ffcdd-7b3f-bc35-6476-258f680cdae9.png)




# トラブルシューティング
KeycloakからAWSコンソール画面に遷移する際，エラーが出ることがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/bb527bed-6579-0763-6197-2d22886e3589.png)
この画面に出てくるエラーメッセージは，次のリンクにリファレンスがあります。個人的にはRole周りの設定を誤って動作しないケースが多かったです。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/troubleshoot_saml.html


# FAQ
- Keycloakのアカウント情報は，IAMに反映される？
いいえ。IAMのユーザカウントが自動的に追加されるようなことはありません。


# 参考サイト
https://xp-cloud.jp/blog/2017/11/09/2261/

https://aws.amazon.com/jp/blogs/big-data/federate-amazon-quicksight-access-with-open-source-identity-provider-keycloak/

https://www.ryuzee.com/contents/blog/7129