OpenAMのSAML認証でAWSへログインするまでの設定

OpenAMの環境構築とSAML認証機能を利用するための初期設定。
いくつかのページで書かれてはいるが、備忘録として。

# OpenAMの環境構築

環境構築は[CloudFormationのテンプレート](https://github.com/ot-nemoto/cloudformation-openam-template)にまとめました。
前提として

- **aws-cli** がインストールされ、プロファイルの設定がされていること
- HostedZoneに **ドメイン** が登録されていること
- 対象のRegionに **キーペア** が作成されていること
- 実行するIAMユーザに十分な権限があること
- OpenAMは事前にForgeRockからダウンロードします(要アカウント登録)
    - CloudFormation でwarファイルをダウンロードするため、ダウンロード可能な場所に配置して下さい
    - 以下の手順でS3へパブリックな環境を構築することも可能です

```sh
# Warを配置するS3バケットを作成
aws cloudformation create-stack \
  --stack-name public-bucket \
  --template-body file://public-bucket-template.yml

# バケット名を取得
BUCKET_NAME=$(aws cloudformation describe-stacks \
  --stack-name public-bucket \
  --query 'Stacks[].Outputs[?OutputKey==`BucketName`].OutputValue' \
  --output text)
echo ${BUCKET_NAME}
  #

# OpenAMのwarファイルをS3にアップロード
aws s3 cp OpenAM-13.0.0.war s3://${BUCKET_NAME}/

# アップロードしたWarファイルのURIを取得
DONWLOD_URI=$(aws cloudformation describe-stacks \
  --stack-name public-bucket \
  --query 'Stacks[].Outputs[?OutputKey==`DownloadUri`].OutputValue' \
  --output text)
echo ${DONWLOD_URI}
  #
```

準備が出来たら環境変数を指定

```sh
# 例)
KEY_NAME=openam-key
HOSTED_ZONE_NAME=example.com.
OPENAM_WAR_URI=${DONWLOD_URI}/OpenAM-13.0.0.war
```

環境構築

```sh
aws cloudformation create-stack \
  --stack-name openam \
  --capabilities CAPABILITY_IAM \
  --parameters ParameterKey=KeyName,ParameterValue=${KEY_NAME} \
               ParameterKey=HostedZoneName,ParameterValue=${HOSTED_ZONE_NAME} \
               ParameterKey=OpenamWarUri,ParameterValue=${OPENAM_WAR_URI} \
  --template-body file://openam-template.yml
```

スタックの実行が完了したら以下でURLを取得できます。
ブラウザでアクセスし、OpenAMの設定を行います。

```sh
DOMAIN=$(aws cloudformation describe-stacks \
  --stack-name openam \
  --query 'Stacks[].Outputs[?OutputKey==`PublicDns`].OutputValue' \
  --output text)
echo http://${DOMAIN}/openam
  #
```

# OpenAMのSAML認証機能設定(AWS)

### 設定オプション

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/d8a0a637-b69a-39d9-3a20-57b25c2ee4c9.png)

- `新しい設定の作成` をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/cf93c5f8-c0c6-013d-805d-ff82519f7792.png)

- `I accept the license agreement` をチェックし、`Continue` をクリック

**一般**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/446d5f2c-29cb-0c2e-f67a-6d7b155ce6ef.png)

- デフォルトのAdministratorユーザ(`amAdmin`)のパスワードを設定し`次へ`をクリック

**サーバー設定**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/9857bfea-91ee-dab5-43e8-54f4abd3a877.png)

- サーバーURL、Cookieドメイン、プラットフォームロケール、設定ディレクトリを指定しますが、デフォルトでも問題ないので、デフォルトで進めます。`次へ`をクリック

**設定データストア設定**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/5429009f-43ab-3418-19fd-add11953b2cc.png)

- デフォルトのまま`最初のインスタンス`を選択したまま、設定ストアの詳細を設定
- 設定データストアは `OpenAM` のまま、ポートを `50389`、管理者ポートを `4444`、JMXポートを `1689` と指定します。
- 暗号化鍵とルートサフィックスはデフォルトのままです。`次へ`をクリック

**ユーザーデータストア設定**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/748d5d36-38d6-2c3c-35c1-b49ee78d6075.png)

- `OpenAMのユーザーデータストア` を選択し、`次へ`をクリック

**サイト設定**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/5e890a59-619f-478d-eb20-690cd854849d.png)

- ロードバランサは今の段階では利用しないので、`いいえ`のままで。`次へ`をクリック

**デフォルトのポリシーエージェントユーザー**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/29898d57-6299-a33c-70c2-9daed1a9cd34.png)

- デフォルトのポリシーエージェント(`UrlAccessAgent`)のパスワードを設定し`次へ`をクリック

**設定ツールの概要と詳細**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/7d638b3c-bca7-6dda-edbf-990d9c8888e9.png)

- `設定の作成`をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/fb528fa7-4b3e-a7bf-c5ae-4000c532120a.png)

- 設定完了後、`ログインへ進む`。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/2925bff4-cd5c-7c6b-017a-e53170bd8bc2.png)

- ユーザとパスワードは、デフォルトのAdministratorユーザ(`amAdmin`)と設定したパスワードで。

### SAML認証機能の設定

**IDP（IDプロバイダ）の設定**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/b0758aa9-1b23-5f07-0826-fb8028509ece.png)

- `Top Level Realm` をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/e31add34-e28f-f78e-209b-9b5375ff0872.png)

- `Create SAMLv2 Providers` をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/24396da3-a101-eac8-ebb6-96eac2bf60f0.png)

- `Create Hosted Identity Provider` をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/1843c478-0ce8-1a2e-4c1f-9d2dbcf1d8ab.png)

- メタデータ
    - 名前は任意ですが、ホスト名を入力
    - 署名鍵はテスト目的なのでデフォルトの `test` で
- トラストサークル
    - 新しいトラストサークルの名称は任意ですが、 `aws` と入力
- `設定`をクリック

**SP（サービスプロバイダ）の設定**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/a72fa7fd-3bd3-c661-5253-cc60a5915be4.png)

- IDPの設定を完了すると、そのままSPの登録へ誘導する画面が表示されます。`サービスプロバイダを登録する`をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/ae7af64f-b854-102d-dc30-2d27f1106250.png)

- メタデータファイルは AWSのURLから取得させます。`URL`を選択し、URLに `https://signin.aws.amazon.com/static/saml-metadata.xml` を入力
- `設定`をクリック

### サービスプロバイダ側（AWS）の設定

**プロバイダの設定**

サービスプロバイダにIdPの登録を行います

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/8d0a5fbc-d325-326e-a73f-54dc387cbe37.png)

- AWSマネージドコンソールにログインし、IAM > ID プロバイダー で `プロバイダの作成`をクリック
    - プロバイダーのタイプ: **SAML**
    - プロバイダ名: OpenAM（任意）
    - メタデータドキュメント: `http://${DOMAIN}/openam/saml2/jsp/exportmetadata.jsp` からメタデータをダウンロードし、ファイル選択で指定
- `次のステップ`をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/586daaac-d7ef-c56d-d976-21e04450f1f2.png)

- 登録内容を確認して、`作成`をクリック

**ロールの設定**

SSOでログインした際のユーザに付与される権限を設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/247aec77-a285-a4fb-b996-d37d512bc978.png)

- IAM > ロール で `ロールの作成` をクリック
    - 信頼されたエンティティの種類を選択: **SAML2.0フェデレーション**
    - SAML2.0プロバイダを選択:
        - SAMLプロバイダー: OpenAM（上記で設定したプロバイダ名）
        - `プログラムによるアクセスとAWSマネジメントコンソールによるアクセスを許可する`を選択
        - 属性、値は自動入力されるのでそのままで
- `次のステップ:アクセス権限`をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/ab00eae7-e7bf-c6cc-973c-f893fd4d69fc.png)

- どの権限を付与するかを指定します。`AdinistratorAccess` を設定していますが、特に何も設定しなくても、マネージドコンソールへログインすることは可能なので任意で。
- `次のステップ:タグ`をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/fb3c09b7-42aa-b399-dd9a-1a45817372ce.png)

- タグも必要であれば設定。`次のステップ:確認`をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/911bb264-a782-d59d-5d4c-ac10e2d766a3.png)

- 任意のロール名を入力し、`ロールを作成`をクリック。サービスプロバイダの設定は以上です。

### SAML連携の設定

連携の設定

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/1b2cbed0-5899-5127-f777-e5f59a6d9524.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/c956396c-41cf-0f53-3958-37b50e654210.png)

- OpenAMにアドミニストレータでログインします。
- FEDERAION > エンティティープロバイダ > `urn:amazon:webservices` > 表明処理
- 属性マップに以下の値を追加
    - `https://aws.amazon.com/SAML/Attributes/Role=employeeNumber`
    - `https://aws.amazon.com/SAML/Attributes/RoleSessionName=uid`

この値ですが、AWSの[メタデータ](https://signin.aws.amazon.com/static/saml-metadata.xml)を見てみましょう。

```xml:saml-metadata.xml
<AttributeConsumingService index="1">
  <ServiceName xml:lang="en">AWS Management Console Single Sign-On</ServiceName>
  <RequestedAttribute isRequired="true" Name="https://aws.amazon.com/SAML/Attributes/Role" FriendlyName="RoleEntitlement"/>
  <RequestedAttribute isRequired="true" Name="https://aws.amazon.com/SAML/Attributes/RoleSessionName" FriendlyName="RoleSessionName"/>
</AttributeConsumingService>
```

メタデータの一部を抜粋していますが、このメタデータを見ると、`<RequestedAttribute isRequired="true">` となって項目があります。
これはSAMLリクエストに `https://aws.amazon.com/SAML/Attributes/Role` および `https://aws.amazon.com/SAML/Attributes/RoleSessionName` を渡す必要があることを意味します。

設定内容は「[認証レスポンスの SAML アサーションを設定する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_create_saml_assertions.html)」を確認してみてください。

この設定で、RoleにemployeeNumber（社員番号）？と思われた方もいると思いますが、実際はOpenAMのユーザ情報のemployeeNumberにRole情報を設定してあげることで、その値（社員番号）をRoleとしてSAMLレスポンスとして返すようにしています。

### SAML連携するユーザの作成

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/ae39e3bf-d89c-796f-207f-d8cfe5df74b0.png)

- TOP LEVEL REALM > Subjects > 新規 でユーザ情報を入力し、`了解` をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/18bf0baf-8851-9889-99d4-cc2518b72803.png)

- ユーザ情報の編集で先ほどの連携する情報を設定します。
    - `uid`: ユーザ作成時のIDになるので設定は不要
    - `employeeNumber`: ロールARN,プロバイダARNを設定（例: *arn:aws:iam::123456789012:role/openam-user-role,arn:aws:iam::123456789012:saml-provider/OpenAM*）
- 設定したら`保存`をクリック

### AWSへOpenAMユーザでログイン

設定は以上になります。
`${OPENAM_URL}/saml2/jsp/idpSSOInit.jsp?metaAlias=/idp&spEntityID=urn:amazon:webservices` をブラウザから叩くとAWSへログイン出来ることが確認できます。（OpenAMへ未ログインの場合は、OpenAMのログイン画面を挟み、ログインするとAWSのポータル画面へリダイレクトされます。）

---

以下は別に必須ではありません。次の設定をすれば、OpenAMへログインしOpenAMのポータル画面からAWSへログインすることも可能になります。
必要であれば設定します。

参考: [OpenAMのダッシュボードにAWSマネジメントコンソールを表示させる方法](https://qiita.com/Tom3/items/da28ea38e05f95728f89)

### ダッシュボードにAWS Consoleを表示させる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/b50e0be1-899f-74ea-61c1-e1a1feb64e2f.png)

- CONFIGURATION > グローバル > ダッシュボード > セカンダリ設定インスタンス > 新規
    - 名前: AWS Console (任意)
    - Dashboard Class Name: SAML2ApplicationClass
    - Dashboard Display Name: AWS Management Console
    - Dashboard Login: `${OPENAM_URL}/saml2/jsp/idpSSOInit.jsp?metaAlias=/idp&spEntityID=urn:amazon:webservices`（**${OPENAM_URL}**は自身の環境に合わせて）
    - Dashboard Name: AWS Management Console（任意）
    - ICF Identifier: 
    - dashboard Icom: `https://pbs.twimg.com/profile_images/917497289710505984/pR-1qA0D_400x400.jpg` (拾ってきた。任意）
- `追加`をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/f36a8619-2168-1c8e-9a3f-98ee9d4d35f4.png)

- Subjects > 対象ユーザ > サービス > ダッシュボード
- ユーザー属性に `AWS Console` を追加し、`保存`をクリック
- 対象ユーザでログインしダッシュボードを開くと以下のように表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/297616/9964e09d-044b-df8e-c95e-3c21325c7230.png)

以上