EC2上に構築したOpenAMのSAMLv2.0FederationよりSSOを実装する

今回SSOを実施するにあたって以下の記事を参照しました。

* [OpenAM as a SAMLv2 IdP for the Amazon Web Services (AWS) - ForgeRock Forum and Blog](https://forum.forgerock.com/2016/02/openam-as-a-samlv2-idp-for-the-amazon-web-services-aws/)
* [Amazon Linux に OpenAM をインストールしてみる - Qiita](https://qiita.com/kusokamayarou/items/3ed839a7e51b8137b87a)
* [OpenAM in Amazon EC2 - OpenAM - Confluence](https://wikis.forgerock.org/confluence/display/openam/OpenAM+in+Amazon+EC2)
* [AWSにOpenAMを使ってSAMLでSSOしてみた - YOMON8.NET](http://yomon.hatenablog.com/entry/2015/10/01/051604)


# 1. IdP側の環境構築
## 1-1. EC2の構築
### 1. EC2インスタンスを作成します。
* AMI: Amazon Linux AMI 2017.09.1 (HVM), SSD Volume Type - ami-ceafcba8
* InstanceType: t2.xlarge
* SecurityGroup:
	* Inbound: HTTP及びSSHのみに設定し、IP制限だけ実施(今回HTTPSは使用しないのと、試験用のためIP制限設定)
	* Outbound: FullAccess

```
🤖 ~  ⌚ 13:06:52
⚡ aws ec2 describe-security-groups --group-names OpenAM | jq '.SecurityGroups[].IpPermissions,.SecurityGroups[].IpPermissionsEgress'
[
  {
    "FromPort": 80,
    "IpProtocol": "tcp",
    "IpRanges": [
      {
        "CidrIp": "<接続元IPaddr>"
      }
    ],
    "Ipv6Ranges": [],
    "PrefixListIds": [],
    "ToPort": 80,
    "UserIdGroupPairs": []
  },
  {
    "FromPort": 22,
    "IpProtocol": "tcp",
    "IpRanges": [
      {
        "CidrIp": "<接続元IPaddr>"
      }
    ],
    "Ipv6Ranges": [],
    "PrefixListIds": [],
    "ToPort": 22,
    "UserIdGroupPairs": []
  }
]
[
  {
    "IpProtocol": "-1",
    "IpRanges": [
      {
        "CidrIp": "0.0.0.0/0"
      }
    ],
    "Ipv6Ranges": [],
    "PrefixListIds": [],
    "UserIdGroupPairs": []
  }
]
```

### 2. ElasticIPの設定
ElasticIPを対象のインスタンスに設定し、IPアドレスを固定します。
(参照) [Elastic IP アドレス - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html)
ドメインの設定(EC2のDHCPoptionで自動設定されるdomainを使用すると失敗したので、今回はRoute53で設定しました。以下Domain: www.example.com とします)
### 3. Network設定
(EC2の作成が完了したら)対象のインスタンスにSSH経由で接続し、`/etc/hosts/`及び、`/etc/sysconfig/network`に以下の内容を追加及び変更します。

```
🤖 ~  ⌚ 13:07:02
⚡ ssh OpenAM

[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo vim /etc/sysconfig/network

HOSTNAME=openam, www.example.com #serverのホスト名とDomain名をFQDN形式で変更します


[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo vim /etc/hosts

<ElasticIPで設定したIPaddress> www.example.com #ElasticIPaddr 及び Domain を追加します
```

以上でEC2の基本設定は完了です。
次にApache+tomcat7でWebserverの設定を実施します。

## 1-2. Webserverの構築
### 1. 必要なpackageのインストール
対象のインスタンスに接続し、必要なApache関連のpackageインストール及び確認を実施します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo yum update -y
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo yum install httpd -y
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo chkconfig httpd on
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo yum install -y openssl openssl-devel mod_ssl
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo service httpd start
Starting httpd:                                            [  OK  ]
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ ps aux | grep httpd
root      8322  0.0  0.9 204156  9608 ?        Ss   06:17   0:00 /usr/sbin/httpd
apache    8324  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
apache    8325  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
apache    8326  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
apache    8327  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
apache    8328  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
apache    8329  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
apache    8330  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
apache    8331  0.0  0.6 204156  6604 ?        S    06:17   0:00 /usr/sbin/httpd
```

これでApacheが起動することを確認できました。
次にtomcat7関連の設定を実施します。最初にJavaの確認だけ実施します。今回使用したEC2には元々OpenJDKベースのJavaがインストールされていますが、これをOracleJDKに変えたい場合は適宜変更ください(OpenJDKでも問題ないです)。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ java -version
java version "1.7.0_161"
OpenJDK Runtime Environment (amzn-2.6.12.0.75.amzn1-x86_64 u161-b00)
OpenJDK 64-Bit Server VM (build 24.161-b00, mixed mode)
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo yum install -y tomcat7 tomcat7-webapps tomcat7-admin-webapps
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo chkconfig tomcat7 on
```

### 2. tomcat7の設定
tomcat7の設定ファイルのバックアップを作成します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ cd /etc/tomcat7/
[ec2-user@ip-xxx-xxx-xxx-xxx tomcat7]$ sudo cp tomcat-users.xml tomcat-users.xml.template
[ec2-user@ip-xxx-xxx-xxx-xxx tomcat7]$ sudo cp server.xml server.xml.template
[ec2-user@ip-xxx-xxx-xxx-xxx tomcat7]$ ls -a
.         catalina.policy      logging.properties   tomcat7.conf               web.xml
..        catalina.properties  server.xml           tomcat-users.xml
Catalina  context.xml          server.xml.template  tomcat-users.xml.template
```

#### `tomcat-users.xml`
各設定ファイルを変更していきます。まずは`tomcat-users.xml`の最下部にある下記内容のコメントアウトを外します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx tomcat7]$ sudo vim tomcat-users.xml

<user name="admin" password="*******" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" />
```

このusernameとpasswordは後にOpenAM関連を設定する際のページを開く際に必要となりますので、適宜変更してください。

元の設定ファイルと比べると以下の内容になります。

```
[ec2-user@ip-xxx-xxx-xxx-xxx tomcat7]$ sudo diff tomcat-users.xml tomcat-users.xml.template
50c50
< <user name="admin" password="*******" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" />
---
> <!-- <user name="admin" password="adminadmin" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" /> -->
```

#### `server.xml`
`<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />`をコメントアウトします。

```
[ec2-user@ip-xxx-xxx-xxx-xxx tomcat7]$ sudo vim server.xml

    <!-- <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" /> -->
```

元の設定ファイルと比べると以下の内容となります。

```
[ec2-user@ip-xxx-xxx-xxx-xxx tomcat7]$ sudo diff server.xml server.xml.template
71c71
<     <!-- <Connector port="8080" protocol="HTTP/1.1"
---
>     <Connector port="8080" protocol="HTTP/1.1"
73c73
<                redirectPort="8443" /> -->
---
>                redirectPort="8443" />
```

### 3. Webserver(Apache+tomcat7)の設定
`/etc/httpd/conf/httpd.conf`に下記内容を追加し、Apacheへの接続をtomcat7側に向けます。

```xml
<Location />
  ProxyPass ajp://localhost:8009/
</Location>
```

Apache及びtomcat7の再起動及び起動します。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo tomcat7 start
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]
```

先ほど設定したDomain(www.example.com)にHTTP経由(http://www.example.com/)で接続し、tomcatのページが表示されることを確認します。

```
🤖 ~  ⌚ 14:02:40
⚡ curl http://www.example.com/ | head -20
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11197    0 11197    0     0   127k      0 --:--:-- --:--:-- --:--:--  128k

<!DOCTYPE html>


<html lang="en">
    <head>
        <title>Apache Tomcat/7.0.84</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

    <body>
        <div id="wrapper">
            <div id="navigation" class="curved container">
                <span id="nav-home"><a href="http://tomcat.apache.org/">Home</a></span>
                <span id="nav-hosts"><a href="/docs/">Documentation</a></span>
                <span id="nav-config"><a href="/docs/config/">Configuration</a></span>
                <span id="nav-examples"><a href="/examples/">Examples</a></span>
                <span id="nav-wiki"><a href="http://wiki.apache.org/tomcat/FrontPage">Wiki</a></span>

```

実際にブラウザ経由で確認すると以下のページが表示されます。
<img width="1280" alt="openam_1_showtomcat.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/63599fbb-066c-b319-1c81-c853e4bcbb62.png">


これでWebserver側の設定は完了です。

# 2. OpenAMインストール及びログインまで
OpenAMについてはForgerockにて管理されており、現在は製品名が変更されているようです。
[OpenAM - Wikipedia](https://ja.wikipedia.org/wiki/OpenAM)
> OpenAMはSun MicrosystemsのOpenSSOを起源に持つ。OracleによるSun Microsystemsの買収後、OracleがOpenSSOの開発中止を決定したため、ForgeRock（英語: ForgeRock）社がその開発とサポートを継続することを2010年2月に発表した。[1]　OpenSSOの製品名はOracleが権利を保持し続けたため、製品名をOpenAMに変更したうえで、ForgeRock社がスポンサーとなるフォークとしてOpenAMがスタートした。  
> ForgeRockはSun Microsystemsのオリジナルのロードマップを提供し続けることをかつて発表していたが、[2][3] 実際には既にオープンソースコミュニティを閉鎖しており、パーミッシブライセンス（英語: Permissive software licence）の元でのプラットフォームの新たな開発を許していない。[4] これ以降オープンソース版のOpenAMは、ForgeRock共同開発パートナー[5][6]のオープンソース・ソリューション・テクノロジ株式会社[7]にて公開が継続されている。なお、OpenAM 14.0 よりForgeRock Access Management 5.0 に製品名が変更された。[8]  

## 2-1. Forgerockでインストールメディアの取得
今回は OpenAM 13.0.0 を使用します。[Downloads - BackStage](https://backstage.forgerock.com/downloads/browse/am/archive?path=%2FOpenAM%20Enterprise%2F13.0.0) より、`.war`ファイルを選択します。
<img width="795" alt="openam_2_installmedia.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/9281184b-20e3-c3fe-0e8c-762c2387bf58.png">


このメディアを対象インスタンスの`/usr/share/tomcat7/webapps`へ移動します。またこの時`.war`の名前を`openam`に変更してから上記ディレクトリに移動します。

## 2-2. OpenAMのインストール及びログイン
再度 http://www.example.com/ よりtomcatのページに戻り、OpenAMの設定を行います。ここからGUI上で行います。
### 1. OpenAMへのアクセス
下記”Manager App”を選択すると、Basic認証が入るので、先ほど`tomcat-users.xml`で設定したusername及びpasswordを入力します。
<img width="686" alt="openam_3_manageapp.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/b642f2e3-a74d-6883-fa08-5cbada17b2d6.png">

すると”Tomcat Webアプリケーションマネージャ“が開くので、下記`/openam`を選択します。
<img width="1150" alt="openam_4_openamSetting.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/47d94b37-77fb-1f7d-a5d1-dadd07ebe3f7.png">


以下の画面が出力されるので、”カスタム設定”を選択します。この後CustomerAgreementの画面が出力されるので、”同意”します。
<img width="1081" alt="openam_5_forgelockSetting.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/4e1384db-35b4-7573-9d94-6eb1d094f6d5.png">




### 2. OpenAMの設定
以下のように設定します。
#### 一般設定
<img width="812" alt="openam_6_1_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/7a9bac06-f00a-3d3c-3f45-ec63f0b84ae1.png">


#### Server設定
<img width="809" alt="openam_6_2_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/d56e7351-5a36-deeb-6b40-6453202c4507.png">



#### 設定ストア
“OpenAM”を選択します。”ホスト名”はそのままで、”Port”、”管理者Port”、”JMXPort”を以下のように設定します。
<img width="811" alt="openam_6_3_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/3c384645-c0ab-3eda-7fe2-e5995004bf85.png">



#### ユーザーデータストア設定
“OpenAM のユーザーデータストア”を選択します。
<img width="813" alt="openam_6_4_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/c57d9dc4-5155-5bfd-f306-509229edf32c.png">



#### サイト設定
今回LBの設定は実施しないので、”いいえ”を選択します。
<img width="811" alt="openam_6_5_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/e191ff6d-8e81-dab3-f130-1f37b5f89211.png">



#### デフォルトのポリシーエージェントユーザー
特に今回はこのユーザーを使用しません。このPasswordは、1つ目に設定した”amAdmin”のPasswordと同様のものは使用できません。
<img width="813" alt="openam_6_6_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/6f03d833-ae0f-442f-c536-269099919cc5.png">



最後に確認画面が表示されるので内容を確認し、OpenAMの設定は完了です。無事設定が完了すると以下の画面が表示されます。失敗した場合はもう一度`.war`ファイルと`/openam`ディレクトリを削除したもう一度やり直す必要があります。
トラシューは [OpenAMインストール時の注意点とトラブルシューティングの方法 | OSS ∞ Lab](https://t246osslab.wordpress.com/2014/10/08/openam%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%99%82%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9%E3%81%A8%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3/) に記載があります。
<img width="813" alt="openam_6_7_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/78bc25b3-ce1d-c5b9-5494-9a4a760c18d0.png">


設定完了後、管理者としてログインします。Passwordには、この”OpenAMの設定”の”一般設定”にて入力したPasswordを入力します。
<img width="1277" alt="openam_6_8_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/eedf2391-8baf-074c-7d18-470c34751453.png">


ログインに成功すると以下の画面が出力されます。
<img width="1280" alt="openam_6_9_openam.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/3ee0546f-080c-c76f-bd03-cd9c59b3ff1e.png">


# 3. CoTの設定
ここからが後半戦です。以下ではIdP(OpenAM)側と、SP(AWS)側の設定を実施します。
## 3-1. IdP(OpenAM)側の設定
ログイン成功後の上記Realmを選択します。その後まずは、IdP側の設定を行うため、以下の”Create SAMLv2 Providers”を選択します。
<img width="443" alt="openam_7_createSAMLprov.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/361b7542-f8b6-4b74-eb3f-3e590c35c107.png">


“Created Hosted Identity Provider”を選択します。
<img width="454" alt="openam_8_idp.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/61a7fd7f-38ed-9f83-31cc-f1cb05e5ca99.png">


以下のような画面が出力されるので、それぞれ入力します(IdP側の名前は今回FQDN形式にしておりますが、デフォルトでも問題はありません)。今回は試験用のため、署名鍵にはtestを用いています。また新しいCoT(Circle of Trust)を”aws”という名前を入力し、右上の”設定”を入力します。
<img width="1275" alt="openam_9_idp-fqdn.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/818eb4d9-0855-d4c5-d950-531a5c103472.png">


以上でIdP側の初期設定は完了です。この後以下の画面が出力されるので、このままSP側の設定を実施します。
<img width="583" alt="openam_10_sp.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/770ef4e7-0ec1-be11-1f35-e3dca67c36a7.png">


上記画面を閉じてしまった場合は、もう一度初期画面からRealmを選択し、”Create SAMLv2 Providers”を選択します。その後、一番右に表示されている”Register Remote Service Provider”を選択します。

## 3-2. SP(AWS)側の設定
[SAML 2.0 ベースのフェデレーションについて - AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_saml.html#CreatingSAML-configuring-IdP) を参考にSAMLmetadataを取得し、AWSをSPとして登録します。

### 1. SAMLmetadataの取得
下記URLよりAWS側のSAMLmetadataを取得し、これを`saml-metadata.xml`として保存します。
https://signin.aws.amazon.com/static/saml-metadata.xml

### 2. OpenAM側でSAMLmetadataの登録
下記内容にしたがって、上記で取得した`saml-metadata.xml`をuploadします。CoTには先ほど作成した”aws”を選択します。
<img width="1280" alt="openam_11_registerSpSaml.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/85356d93-4650-566c-2320-3525c29c1943.png">


ここからはAWSマネジメントコンソール(以下AWS-MCと呼びます)側で設定を行います。
### 3. SAMLproviderの作成
基本的に [SAML ID プロバイダーの作成 - AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_create_saml.html) の内容に従います。

まずは下記URLより、IdP側のSAMLmetadataを取得し、これを`exportmetadata.jsp.xml`として保存します。
http://www.example.com/openam/saml2/jsp/exportmetadata.jsp

次にAWS-MCにログインし、IAMコンソールを開きます。左側のナビゲーションペインより”IDプロバイダ”を選択し、”プロバイダの作成”よりSAMLプロバイダを作成します。
以下の画面で、”SAML”を選択します。
<img width="514" alt="openam_12_1_createSamlProvider.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/281c369a-9f8d-9cbb-4392-9b596318d034.png">


次にProviderの設定において、”プロバイダ名”を任意に設定し、先ほど取得した`exportmetadata.jsp.xml`をuploadします。
<img width="705" alt="openam_12_2_createSamlProvider.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/dc2cb1b0-9b15-998f-592a-2a800db1dd17.png">


### 4. IAMroleの作成
上記プロバイダーを使用するには、IAMroleを作成し、SAMLproviderと信頼関係を設定する必要があります。
(参考) [SAML 2.0 フェデレーション用のロールの作成 (コンソール) - AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html)

IAMコンソールより左側のナビゲーションペインから、”ロール”を選択し、”ロールの作成”よりIAMroleを作成します。
以下の内容でRoleを設定します(今回はSAMLresponseの確認のためコンソールへのログインも実施できるように設定しております)。
<img width="1280" alt="openam_13_1_role.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/6760d9e9-5e7f-5703-b404-8c0d4ecbd20c.png">


次にSAML認証を実施したユーザーのAWSリソースへのアクセス権限を行います。今回は簡単のため”AmazonS3FullAccess”を設定しました。そして、Role名を”saml-provider-role”(任意)とし、設定内容を確認します。

```
🤖 ~  ⌚ 21:26:08
⚡ aws iam get-role --role-name saml-provider-role
{
    "Role": {
        "Path": "/",
        "RoleName": "saml-provider-role",
        "RoleId": "<Role-ID>",
        "Arn": "arn:aws:iam::<AccountID>:role/saml-provider-role",
        "CreateDate": "2018-03-04T12:23:41Z",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Federated": "arn:aws:iam::<AccountID>:saml-provider/openanm-saml-provider"
                    },
                    "Action": "sts:AssumeRoleWithSAML",
                    "Condition": {
                        "StringEquals": {
                            "SAML:aud": "https://signin.aws.amazon.com/saml"
                        }
                    }
                }
            ]
        },
        "Description": "For SAMLfederation"
    }
}

```

これでAWS-MCでの設定は完了です。

## 3-3. Provider, Userの設定
### 1. Attribute Mapperの設定
AWSログインに必要な属性値についてここで設定します。
まず、もう一度Forgerockのtopページに戻り、以下のように”Federation”を選択します。
<img width="624" alt="openam_14_fedaration.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/1da24e76-ce5a-5eed-2d80-392f510c5e35.png">


ここでCoTの設定について確認できます。CoTには
* 名前: aws, Entity: urn:amazon:webservices|saml2 及び、www.example.com が確認できます

Entity Prviderには以下の内容が確認できます。
* www.example.com, IdP, ホスト
* urn:amazon:webservices, SP, リモート

Entity Providerにおける”urn:amazon:webservices”を選択します。
<img width="1245" alt="openam_15_1_entityProviderSetting.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/6a3c8f60-4b75-abac-4a68-517846053bd0.png">


次に上部のタブより、”表明処理”(Attribute Processing)を選択します
<img width="225" alt="openam_15_2_entityProviderSetting.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/28568c56-022b-aa3b-b90f-384614f8589f.png">


“属性マッパー”に以下の内容を追加します。
* https://aws.amazon.com/SAML/Attributes/Role=employeeNumber
* https://aws.amazon.com/SAML/Attributes/RoleSessionName=uid

ここの設定を誤るとAWS-MCにSSO経由でログインする際にSAMLassertionの受け渡しが失敗して、`Your request included an invalid SAML response.`が出力されます。[AWS での SAML 2.0 フェデレーションのトラブルシューティング - AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/troubleshoot_saml.html#troubleshoot_saml_missing-rolesessionname) にも記載があります。
> このエラーは、ID プロバイダからの SAML レスポンスに、Name が https://aws.amazon.com/SAML/Attributes/RoleSessionName に設定された属性が含まれない場合に発生することがあります。属性値は、ユーザーの ID で、通常は ID または E メールアドレスです。
  
<img width="684" alt="openam_15_3_entityProviderSetting.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/f024a042-ad76-7456-08a6-992d20087559.png">



上記設定を確認後、”保存”します。

### 2. ログインUserの作成
もう一度Forgerockのtopページに戻り、Realmを選択します。そして画面左側の”subjects”を選択し、Userを追加します。
<img width="331" alt="openam_16_1_LoginUser.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/c93bd8c0-5fa1-a04a-087d-fb2d412afb03.png">


既に`amAdmin`, `anonymous`, `demo`Userは作成されております。なお汎用IDがAWS-MCにログインする際に必要なIDです。
<img width="778" alt="openam_16_2_LoginUser.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/b0415075-3cb1-d046-7149-844712ebeb1a.png">


“新規”より下記のようなUser”login-user”を作成します(入力内容は任意)。
<img width="530" alt="openam_16_3_LoginUser.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/170fe3b7-7171-7dcb-54e9-021aeb7624e4.png">


Userが作成されているか確認します。
<img width="764" alt="openam_16_4_LoginUser.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/2900c835-b7f8-0a02-d10d-fcc0fd4763af.png">


その後この”openam”を選択し、下記内容でemployeeNumberにペアで設定します。先ほど設定した属性値にこのペアで権限等が渡されます。
`arn:aws:iam::<AccountID>:role/saml-provider-role,arn:aws:iam::<AccountID>:saml-provider/openanm-saml-provider`

上記内容で設定後”保存”します。ここまででIdP及びSPの設定は完了です。いよいよAWS-MCにログインします。

## 3-4. AWS-MCへのログイン
下記URLにアクセスすると、ログイン画面となります。(この時”amAdmin”でログアウトしておきます。しないでおくと、上記で登録したemployeeNumberの属性値に合致せず、`Your request included an invalid SAML response.`が出力されます)。
http://www.example.com/openam/saml2/jsp/idpSSOInit.jsp?metaAlias=/idp&spEntityID=urn:amazon:webservices

補足ですが、この`idpSSOInit.jsp`は実際に対象のインスタンスにSSH経由でログインし、`<openamのディレクトリ>/saml2/jsp`より確認できます。OpenAMのVersionが古い場合は下記URLにアクセスします。
http://www.example.com/openam/idpssoinit?metaAlias=/idp&spEntityID=urn:amazon:webservices

ここで、先ほど登録したUser情報を入力します。
* Username: login-user
* Password: <設定したPassword>
<img width="1280" alt="openam_17_login.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/59398479-0b98-c35d-9ad8-5f8f4bef27ad.png">


SAMLresponseがうまく渡せると、下記のようにログインできます。
<img width="624" alt="openam_18_completeLogin.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/5bd352d3-b8a5-6dc2-1c18-661c53770bba.png">


これでSAMLv2により、一時認証情報を取得し、AWS-MCにログインできることが確認されました。次にSAMLassertionを取り出し、AWS CLIコマンドを実行します。

# 4. SAMLresponseの抽出及びAWS CLI実行
今回はブラウザとしてGoogle Chromeを使用し、デベロッパツールを利用します。下記ドキュメントを参考に実施します。
[トラブルシューティングのためにブラウザで SAML レスポンスを表示する方法 - AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/troubleshoot_saml_view-saml-response.html#chrome)

## 4-1. デベロッパツールの立ち上げ
以下のように、デベロッパーツールの上部における"Network"タブよりより、"Preserve log"を選択します
<img width="1280" alt="openam_19_1_samlassertion.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/46e2e7a3-da91-bfe1-f1c6-cc23e9482cae.png">


## 4-2. SAMLresponseの取得
“4-1”にてUsername及びPasswordを入力し、SSOでAWS-MCにログインします。”saml”でfilterをかけ、SAMLreponseを取り出します。
<img width="671" alt="openam_19_2_samlassertion.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/497ad4df-b374-75e4-5295-30d1f7ed74da.png">


以下のようにSAMLResponseを取得できます。
<img width="449" alt="openam_19_3_samlassertion.png" src="https://qiita-image-store.s3.amazonaws.com/0/179534/af6f606a-52e5-1d98-407f-d1597ba2b34c.png">


このSAMLresponseをローカル上に`samlresp.txt`の名前で保存します。

```
🤖 ~  ⌚ 23:46:53
⚡ cat samlresp.txt| head -2
PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6
cHJvdG9jb2wiIElEPSJzMjFlODEyMTEzODgwMTE1Y2VjZDU0ODM1NjFhMjNhNDVkZTRlMmQyODIi
```

## 4-3. 一時認証情報の取得
下記AWS CLIコマンドによりSAMLresponseを利用し、一時認証情報を取得します。本コマンドの詳細は[assume-role-with-saml — AWS CLI 1.14.50 Command Reference](https://docs.aws.amazon.com/ja_jp/cli/latest/reference/sts/assume-role-with-saml.html)に記載がございます。

```
🤖 ~  ⌚ 23:47:22
⚡ aws sts assume-role-with-saml --role-arn arn:aws:iam::<AccountID>:role/saml-provider-role --principal-arn arn:aws:iam::<AccountID>:saml-provider/openanm-saml-provider --saml-assertion file://samlresp.txt
{
    "Credentials": {
        "AccessKeyId": "<AccessKeyID>",
        "SecretAccessKey": "<SecretKey>",
        "SessionToken": "<一時認証token>",
        "Expiration": "2018-03-04T15:50:09Z"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "<AssumeRoleID>:login-user",
        "Arn": "arn:aws:sts::<AccountID>:assumed-role/saml-provider-role/login-user"
    },
    "Subject": "**************",
    "SubjectType": "transient",
    "Issuer": "www.example.com",
    "Audience": "https://signin.aws.amazon.com/saml",
    "NameQualifier": "******************"
}
```

## 4-4. 一時認証情報の記載
`~/.aws/credentials`に一時認証情報を記載します。

```
[saml]
aws_access_key_id = <AccessKeyID>
aws_secret_access_key = <SecretKey>
aws_session_token = <一時認証token>
```

## 4-5. 権限の確認
`saml-provider-role`にはS3のフルアクセス権限のみあるので、実際に反映されているか確認します。

```
🤖 ~  ⌚ 23:51:41
⚡ aws s3api list-buckets --profile saml | head -10
{
    "Buckets": [
        {
            "Name": "<BucketA>",
            "CreationDate": "<Date>"
        },
        {
            "Name": "<BucketB>",
            "CreationDate": "<Date>"
        },

```

```
🤖 ~  ⌚ 23:53:00
⚡ aws ec2 describe-instances --profile saml --region ap-northeast-1

An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
```

以上より、S3アクセス権限があり、EC2等にはAPIcallできないことが確認できます。