ブログ

ryuzeeによるブログ記事。不定期更新

直近開催のScrum Alliance認定スクラムマスター研修のご案内

Keycloakを使ってAWSにSSO接続する方法

みなさんこんにちは。@ryuzeeです。

たくさんのAWSアカウントを持っていたり、さまざまな外部サービスを使っていたりすると面倒なのが、アカウント自体の管理です。 今日はKeycloakを使って、たくさんのAWSアカウントにSSO接続するようにしてみたいと思います。

Keycloakとは

Keycloakは認証・認可のためのオープンソースソフトウェアです。最新のバージョンは4.1.0です。 より詳細については@ITの記事がわかりやすいです。

Keycloakの導入

KeycloakはJavaで書かれており、動作にはアプリケーションサーバが必要です。 アプリケーションで利用可能なデータベースは、MySQL、PostgreSQL、MariaDB、そして主に開発や試用用途のH2です。

また、公式のDockerイメージも用意されており、それを使えばアプリケーションサーバの設定などは不要です。 今回は簡単にするため、Dockerを使ってみましょう。

docker-composeを使うのが簡単で、以下から入手できます。

ここでは、PostgreSQLを使います。

wget https://github.com/jboss-dockerfiles/keycloak/raw/master/docker-compose-examples/keycloak-postgres.yml
docker-compose -f keycloak-postgres.yml

とすれば起動します。起動後にhttp://localhost:8080にアクセスして以下のような画面が表示されればOKです。

Keycloakへのログイン

画面のAdministration Consoleをクリックして管理者画面にログインします。 管理者アカウントの初期ユーザーとパスワードはdocker-composeの中で、KEYCLOAK_USERKEYCLOAK_PASSWORDで定義されているので、それを使います。

ログイン後には以下のような画面が表示されます。

ここは特にいじる箇所がないので、AWSのSSOの設定に進みましょう。

AWSのSAML情報を取得する

まず、AWSのSAML情報を以下のコマンドで取得し、ローカルに保存します。

wget https://signin.aws.amazon.com/static/saml-metadata.xml

クライアントを追加する

Clientsにアクセスすると、以下のようにクライアントの一覧が表示されます。 画面右側にあるCreateボタンをクリックします。

クライアントの追加画面が下のように表示されます。

  • Importを選択し、先程ダウンロードしたsaml-metadata.xmlを指定します
  • Base URLには/auth/realms/master/protocol/saml/clients/amazon-awsを指定します
  • IDP Initiated SSO URL Nameにはamazon-awsを指定します

それが終わったらSaveボタンをクリックします。 以下のような画面が表示されるはずです。

AWSのSAML Provider用の設定ファイルを取得する

Installation タブにアクセスし、SAML Metadata IDPSSODescriptorを選択します。 以下のように表示されますので、Downloadをクリックしてファイルを保存します。 client-tailored-saml-idp-metadata.xmlという名前のファイルができたことを確認しておきます。

AWS(統合したいアカウントそれぞれ)上でSAML Providerの設定をする

SSO接続したいAWSアカウントの設定を行います。

  • マネジメントコンソールでIAMにアクセスし、Identity providers(日本語だとIDプロバイダ)を選択します
  • Create Providerをクリック。Provider TypeSAMLを選択します
  • Provider Nameには適当な名前を指定します
  • Metadata Documentには先ほどKeycloakからダウンロードしたXML(client-tailored-saml-idp-metadata.xml)を指定します

なお、awscliを利用する場合は以下のようなコマンドで作成できます(nameオプションは自分の好みにします)。

aws iam create-saml-provider --saml-metadata-document file://./client-tailored-saml-idp-metadata.xml --name docker-keycloak

ここで作成されたSAMP ProviderのARN(arn:aws:iam::211111666666:saml-provider/docker-keycloakのようなもの)は後で使いますので控えておきます(※1)。

AWS(統合したいアカウントそれぞれ)上にIAM Roleを作成する

次に、SSO経由でログインしたユーザーに割り当てるIAM Roleを作成します。

またIAM Roleの画面で信頼関係を編集し、以下のようなポリシードキュメントに更新します。 Principalの値は各自異なります(アカウント番号やSAM Provierの名前など自分のものに合わせます)。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::211111666666:saml-provider/docker-keycloak"
      },
      "Action": "sts:AssumeRoleWithSAML",
      "Condition": {
        "StringEquals": {
          "SAML:aud": "https://signin.aws.amazon.com/saml"
        }
      }
    }
  ]
}

なお、CloudFormationで作成したい場合は、こちらからスクリプトをダウンロードし、中身を書き換えて(RoleNameなど)以下のように実行すると良いでしょう。

aws cloudformation create-stack --capabilities CAPABILITY_NAMED_IAM --stack-name sso-roles --template-body file://./sso-roles-cfn.yaml

ここで作成したIAM RoleのARNもあとで使いますので控えておきます(※2)。

以上ができたらKeycloak側に戻ります。

ロールの作成

新規でロールを作成するためにAdd Roleを選択します。 以下のような画面が表示されるので、

  • Nameの箇所にIAM RoleのARN、SAML ProviderのARNをカンマで結合して入力します(※1と※2を結合します)。
  • Descriptionの箇所は説明なので、適当に入れておきます。

入力が終わったらSaveをクリックします。

この作業もSSO対象のAWSアカウントの数だけ繰り返します。

Mapperの定義

次にMapperを定義します。Mappersを選択して、Createをクリックして3つの設定を作成します。

  • Session Role
    • Name:Session Role
    • Mapper Type: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
    • 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
    • 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

入力の結果、以下のようになればOKです。

続いてClient Scopesを選択し、Assigned Default Client Scopesの中にrole_listがある場合はRemove selectedをクリックして選択を解除します。 以下のようになれば大丈夫です。

スコープの設定

次にScopeにアクセスし、Full Scope Allowed をOffに設定します。

以上で、クライアントの設定は終了です。

ユーザー作成

続いてユーザーを作成して、権限を割り当てていきます。

左ナビゲーションのUsersを選択すると、一覧画面が表示されるので、Add userをクリックします。 そこで必要な情報を入力してSaveします。以下のような画面が表示されるはずです。

Rolle Mappingsタブに移動すると、左側にClient Rolesのプルダウンからurn:amazon:webservicesを選択します。 Available Rolesの中から当該のアカウントに割り当てたいロールを選択して、Add selectedを選択します。

この作業は利用するAWSアカウント分繰り返します。

また初期パスワードも設定します。Credentialsタブに移動して、Manage Passwordの項目を設定しておきます。

準備完了

以上で準備完了です。

http://localhost:8080/auth/realms/master/protocol/saml/clients/amazon-awsにアクセスして、ログインすると、AWSの画面が次のような感じで表示されれば成功です。

おまけ

このままだと、ローカルのPC上なので実用できないので、Azure上に環境を用意します。

Azure上に環境を作るときは、Azure Cloud Shellを活用するのが便利です。以下を貼り付けると10分くらいで環境が出来上がります(※パスワードなどは適宜変更します)。 なお、追加のパラメータでJDBCの設定をしておくとよさそうです。

export rand=$RANDOM
export resourcegroup=keycloak-$rand
export appservice_plan=appserviceplan$rand
export appservice_name=keycloak-app-$rand
export region='Japan West'
export appservice_instance=B1
export db_server_name=db$rand
export db_admin_user=adminuser
# !!!CHANGE VALUE!!!
export db_admin_password=CHANGE_ME_CHANGE_ME!
export db_sku=B_Gen4_1
export db_firewall_rule=db$rand
export db_name=keycloak$rand
export db_addr="$db_server_name.postgres.database.azure.com"
export db_vendor=postgres
export container_image=jboss/keycloak
export keycloak_user=admin
# !!!CHANGE VALUE!!!
export keycloak_password=CHANGE_ME_CHANGE_ME!

az group create \
   --name "$resourcegroup" \
   --location "$region"

az appservice plan create \
   --name "$appservice_plan" \
   --resource-group "$resourcegroup" \
   --sku "$appservice_instance" \
   --is-linux

az postgres server create \
   --resource-group "$resourcegroup" \
   --name "$db_server_name" \
   --location "$region" \
   --admin-user "$db_admin_user" \
   --admin-password "$db_admin_password" \
   --sku-name "$db_sku" \
   --storage-size 51200 \
   --version "9.6" \
   --ssl-enforcement "Disabled"

az postgres server firewall-rule create \
   --name "$db_firewall_rule" \
   --server "$db_server_name" \
   --resource-group "$resourcegroup" \
   --start-ip-address 0.0.0.0 \
   --end-ip-address 255.255.255.255

az postgres db create \
   --resource-group "$resourcegroup" \
   --server-name "$db_server_name" \
   --name "$db_name"

az webapp create \
   --resource-group "$resourcegroup" \
   --plan "$appservice_plan" \
   --name "$appservice_name" \
   --deployment-container-image-name "$container_image"

az webapp config appsettings set \
   --resource-group "$resourcegroup" \
   --name "$appservice_name" \
   --settings \
     PROXY_ADDRESS_FORWARDING=true \
     DB_VENDOR=$db_vendor \
     DB_DATABASE="$db_name" \
     DB_ADDR="$db_addr" \
     DB_USER="$db_admin_user@$db_server_name" \
     DB_PASSWORD="$db_admin_password" \
     KEYCLOAK_USER="$keycloak_user" \
     KEYCLOAK_PASSWORD="$keycloak_password" \
     JDBC_PARAMS="autoReconnect=true"

それでは。

アジャイル開発チーム向けのコーチングや、技術顧問、Scrum Alliance認定スクラムマスター研修などのトレーニングを提供しています。お気軽にご相談ください(初回相談無料)
前の記事 【書籍紹介】Fifty Quick Ideas To Improve Your User Stories
次の記事 スクラムで削除された5つのトピック

プロダクト開発で、こんな課題を感じていませんか?

  • 何を作るべきか、順位の決め方が定まらない
  • プロダクトの方向性をチームで共有できていない
  • 開発組織の体制や役割がうまく機能していない
  • 開発プロセスが形骸化し、目的を見失っている
  • アジャイルを導入したが、組織に定着しない

プロダクトマネジメント、組織構造、開発プロセスの課題について、組織全体の視点から支援します。

お問い合わせ(初回相談無料)

契約を前提にした相談でなくて構いません。相談に際して事前の整理や準備は不要です。

ダイナミックリチーミング 第2版
Tidy First?
脳に収まるコードの書き方
プロダクトマネージャーのしごと 第2版
エンジニアリングマネージャーのしごと
チームトポロジー
スクラム実践者が知るべき97のこと
プロダクトマネジメント
SCRUM BOOT CAMP THE BOOK
みんなでアジャイル
レガシーコードからの脱却
Effective DevOps
変革の軌跡
ジョイ・インク
アジャイルコーチの道具箱
カンバン仕事術
Software in 30 Days
How to Change the World