今回SSOを実施するにあたって以下の記事を参照しました。
- OpenAM as a SAMLv2 IdP for the Amazon Web Services (AWS) - ForgeRock Forum and Blog
- Amazon Linux に OpenAM をインストールしてみる - Qiita
- OpenAM in Amazon EC2 - OpenAM - Confluence
- AWSにOpenAMを使ってSAMLでSSOしてみた - YOMON8.NET
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
ドメインの設定(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側に向けます。
<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>
これでWebserver側の設定は完了です。
2. OpenAMインストール及びログインまで
OpenAMについてはForgerockにて管理されており、現在は製品名が変更されているようです。
OpenAM - Wikipedia
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 より、.war
ファイルを選択します。
このメディアを対象インスタンスの/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を入力します。
すると”Tomcat Webアプリケーションマネージャ“が開くので、下記/openam
を選択します。
以下の画面が出力されるので、”カスタム設定”を選択します。この後CustomerAgreementの画面が出力されるので、”同意”します。
2. OpenAMの設定
以下のように設定します。
一般設定

Server設定

設定ストア
“OpenAM”を選択します。”ホスト名”はそのままで、”Port”、”管理者Port”、”JMXPort”を以下のように設定します。
ユーザーデータストア設定
サイト設定
デフォルトのポリシーエージェントユーザー
特に今回はこのユーザーを使用しません。このPasswordは、1つ目に設定した”amAdmin”のPasswordと同様のものは使用できません。
最後に確認画面が表示されるので内容を確認し、OpenAMの設定は完了です。無事設定が完了すると以下の画面が表示されます。失敗した場合はもう一度.war
ファイルと/openam
ディレクトリを削除したもう一度やり直す必要があります。
トラシューは OpenAMインストール時の注意点とトラブルシューティングの方法 | OSS ∞ Lab に記載があります。
設定完了後、管理者としてログインします。Passwordには、この”OpenAMの設定”の”一般設定”にて入力したPasswordを入力します。
3. CoTの設定
ここからが後半戦です。以下ではIdP(OpenAM)側と、SP(AWS)側の設定を実施します。
3-1. IdP(OpenAM)側の設定
ログイン成功後の上記Realmを選択します。その後まずは、IdP側の設定を行うため、以下の”Create SAMLv2 Providers”を選択します。
“Created Hosted Identity Provider”を選択します。
以下のような画面が出力されるので、それぞれ入力します(IdP側の名前は今回FQDN形式にしておりますが、デフォルトでも問題はありません)。今回は試験用のため、署名鍵にはtestを用いています。また新しいCoT(Circle of Trust)を”aws”という名前を入力し、右上の”設定”を入力します。
以上でIdP側の初期設定は完了です。この後以下の画面が出力されるので、このままSP側の設定を実施します。
上記画面を閉じてしまった場合は、もう一度初期画面からRealmを選択し、”Create SAMLv2 Providers”を選択します。その後、一番右に表示されている”Register Remote Service Provider”を選択します。
3-2. SP(AWS)側の設定
SAML 2.0 ベースのフェデレーションについて - AWS Identity and Access Management を参考に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”を選択します。
ここからはAWSマネジメントコンソール(以下AWS-MCと呼びます)側で設定を行います。
3. SAMLproviderの作成
基本的に SAML ID プロバイダーの作成 - AWS Identity and Access Management の内容に従います。
まずは下記URLより、IdP側のSAMLmetadataを取得し、これをexportmetadata.jsp.xml
として保存します。
http://www.example.com/openam/saml2/jsp/exportmetadata.jsp
次にAWS-MCにログインし、IAMコンソールを開きます。左側のナビゲーションペインより”IDプロバイダ”を選択し、”プロバイダの作成”よりSAMLプロバイダを作成します。
以下の画面で、”SAML”を選択します。
次にProviderの設定において、”プロバイダ名”を任意に設定し、先ほど取得したexportmetadata.jsp.xml
をuploadします。
4. IAMroleの作成
上記プロバイダーを使用するには、IAMroleを作成し、SAMLproviderと信頼関係を設定する必要があります。
(参考) SAML 2.0 フェデレーション用のロールの作成 (コンソール) - AWS Identity and Access Management
IAMコンソールより左側のナビゲーションペインから、”ロール”を選択し、”ロールの作成”よりIAMroleを作成します。
以下の内容でRoleを設定します(今回はSAMLresponseの確認のためコンソールへのログインも実施できるように設定しております)。
次に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”を選択します。
ここで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”を選択します。
次に上部のタブより、”表明処理”(Attribute Processing)を選択します
“属性マッパー”に以下の内容を追加します。
- 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 にも記載があります。
このエラーは、ID プロバイダからの SAML レスポンスに、Name が https://aws.amazon.com/SAML/Attributes/RoleSessionName に設定された属性が含まれない場合に発生することがあります。属性値は、ユーザーの ID で、通常は ID または E メールアドレスです。

上記設定を確認後、”保存”します。
2. ログインUserの作成
もう一度Forgerockのtopページに戻り、Realmを選択します。そして画面左側の”subjects”を選択し、Userを追加します。
既にamAdmin
, anonymous
, demo
Userは作成されております。なお汎用IDがAWS-MCにログインする際に必要なIDです。
“新規”より下記のようなUser”login-user”を作成します(入力内容は任意)。
その後この”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>

SAMLresponseがうまく渡せると、下記のようにログインできます。
これでSAMLv2により、一時認証情報を取得し、AWS-MCにログインできることが確認されました。次にSAMLassertionを取り出し、AWS CLIコマンドを実行します。
4. SAMLresponseの抽出及びAWS CLI実行
今回はブラウザとしてGoogle Chromeを使用し、デベロッパツールを利用します。下記ドキュメントを参考に実施します。
トラブルシューティングのためにブラウザで SAML レスポンスを表示する方法 - AWS Identity and Access Management
4-1. デベロッパツールの立ち上げ
以下のように、デベロッパーツールの上部における"Network"タブよりより、"Preserve log"を選択します
4-2. SAMLresponseの取得
“4-1”にてUsername及びPasswordを入力し、SSOでAWS-MCにログインします。”saml”でfilterをかけ、SAMLreponseを取り出します。
この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に記載がございます。
🤖 ~ ⌚ 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できないことが確認できます。