OpenAM構築


## Install

- [公式](https://backstage.forgerock.com/#!/downloads)よりOpenAMのwarファイルをダウンロード。

- 依存パッケージのインストール

```
yum install java-1.6.0-openjdk
yum install tomcat6 tomcat6-webapps tomcat6-admin-webapps
```

- hostnameの設定

※ここと後述のOpenAM設定のhostnameが一致していないとエラーでインストール出来ないので注意。

```bash
$ cat /etc/sysconfig/networkk

openam-test.example.com
```

- SELinuxをDisabled

```
cat /etc/sysconfig/selinux
SELINUX=disabled
```

- tomcatのmanagerユーザ追加

```
vim /etc/tomcat6/tomcat-users.xml

# 以下を追加
<role rolename="manager"/>
  <user username="admin" password="password" roles="manager"/>
```

- 設定ファイルの書き込みが出来るようにする。

```
chown -R root:tomcat /usr/share/tomcat6
```

- example.com:8080にアクセス。

- カスタム設定から設定をしていく

- デフォルトユーザ
pass: password

- ポリシーエージェント
pass: agentpassword

```
設定ストアの詳細 編集...
SSL が有効 
ホスト名 
待機ポート 
ルートサフィックス 
ユーザー名 
ディレクトリ名	いいえ 
localhost 
50389 
dc=example,dc=com 
cn=Directory Manager 
/usr/share/tomcat6/OpenAM-11.0.0
ユーザーストアの詳細 編集...
SSL が有効
ホスト名
待機ポート
ルートサフィックス
ユーザー名
ユーザーデータストアタイプ	いいえ
172.16.42.120
389
dc=example,dc=com
cn=Directory Manager
OpenDJ
サイト設定の詳細 編集...
このインスタンスは、ロードバランサの背後には設定されません。

```

エラーが出たら設定用のフォルダが既に出来ているので一度削除してから再度入れなおす


## GoogleAppsでSSO連携

### 方針

- Google AppsとLDAPのアカウントをひもづける
- 基本的にLDAPにあるアカウントを元にGoogle Appsにprovisioningする
- SSOが必要な社内サイトについてはapacheやnginxにwebagentを入れる
- 既にGoogle Appsと連携できているシステム(Gitlab、Jenkins)についてはそのまま継続。ログインの際にOpenAMに飛ばされるだろうから問題なし。
- GoogleAppsでパスワード変更しようとするとOpenAMに飛ばされる仕組み。
- ユーザから見ればGoogleAppsのユーザとパスワードでログインしてるように見えればOK。
- OpenAMのデータストアをどうするか。

### OpenAM設定

参照 :[SIOS "OSSよろず" ブログ出張所: OpenAM を使ってシングルサインオンを構築する (Google Apps 連携編)](http://sios-oss.blogspot.jp/2012/10/openam-google-apps.html)

#### ホストアイデンティティープロバイダを追加

管理者画面「共通タスク」->ホストアイデンティティープロバイダの作成

   - メタデータ

   http://openam-test.example.com:8080/openam

   - トラストサークル

  example_cot

   - 鍵
   test

「シングルサインオン用の Google Apps の設定」
よりtako.asiaを新しい値に追加->作成を押下しSSO用のURLを表示させる。

- サインインページのURL

http://openam-test.example.com:8080/openam/SSORedirect/metaAlias/idp

- サインアウトページのURL

http://openam-test.example.com:8080/openam/UI/Logout?goto=http://openam-test.example.com:8080/openam

- パスワード変更のURL

http://openam-test.example.com:8080/openam/idm/EndUser


- 検証証明書

```
-----BEGIN CERTIFICATE-----
MIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh
bGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w
〜中略〜
QzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA
cGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC
/FfwWigmrW0Y0Q==
-----END CERTIFICATE-----
```

#### SSOの検証項目

- 有効にするまえにやらなければいけないこと
  
  - SSOを有効する前に存在するユーザの作成(そのユーザのデータはどうなるかの検証)
     -> 既に存在するIDの場合消えるということはなかった
  - SSOを有効にする前のユーザのパスワードはどうなるか(有効後にも同じパスワードで出来るのか)
     -> SSOを経由しない認証のみSSOが有効になる前のパスワードが使われる。
- 有効にした後にやること
  - SSOを有効にする前から存在するユーザのデータの確認
     -> 特に変化なし。メール、ドライブのデータも消えない。万が一間違ってユーザを消してしまった場合は管理者メニューの復元からユーザを復元することが出来る。消したユーザIDで先にユーザを新規作成してしまうと復元が出来なくなるので注意。
  - SSOを有効にした後LDAPに作成したユーザのprovisioning&データの確認
     -> ID、名前等は反映されるもののパスワードが反映されず不完全。SSOを有効にしたことによりパスワードのprovisioningが出来なくなったのかもしれないが、メールソフト等使ってる場合どうなるだろう？iPhone標準メールアプリはSSOに対応してなさそうなので無理かもしれないが、Gmailアプリなら見れそうな感じだった。
  - SSOを介さない認証はLDAPとGoogleAppsどちらのパスワードが使われるか。
     -> 


## OpenAMにカスタム属性を追加

参照: [Chapter 14. Customizing Profile Attributes](http://docs.forgerock.org/en/openam/11.0.0/dev-guide/index/chap-custom-attr.html)

```/usr/share/tomcat6/openam/config/xml/amUser.xml
以下の行を<User>内に追加
<AttributeSchema name="customAttribute"
    type="single"
    syntax="string"
    any="display"
    i18nKey="Custom Attribute">
</AttributeSchema>
```

iPlanetServiceを削除して追加しなおす

```bash
$ cd /path/to/tools/openam/bin/
$ ssoadm
 delete-svc
 --adminid amadmin
 --password-file /tmp/pwd.txt
 --servicename iPlanetAMUserService
 
Service was deleted.
$ ssoadm
 create-svc
 --adminid amadmin
 --password-file /tmp/pwd.txt
 --xmlfile $HOME/openam/config/xml/amUser.xml
 
Service was added.
```

- openamの設定を変更する(LDAP管理)

```bash
./opends/bin/ldapsearch -h localhost -p 50389 -D "cn=Directory Manager" -w password -b "dc=example,dc=com" ou=SelfWriteAttributes

dn: ou=SelfWriteAttributes,ou=Policies,ou=default,ou=OrganizationConfig,ou=1.0,o
 u=iPlanetAMPolicyService,ou=services,o=sunamhiddenrealmdelegationservicepermiss
 ions,ou=services,dc=example,dc=com
ou: SelfWriteAttributes
objectClass: organizationalUnit
objectClass: sunServiceComponent
objectClass: top
sunserviceID: NamedPolicy
sunKeyValue:: eG1scG9saWN5PTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cj
 xQb2xpY3kgbmFtZT0iU2VsZldyaXRlQXR0cmlidXRlcyIgY3JlYXRlZGJ5PSJjbj1kc2FtZXVzZXIsb
 3U9RFNBTUUgVXNlcnMsZGM9ZXhhbXBsZSxkYz1jb20iIGxhc3Rtb2RpZmllZGJ5PSJjbj1kc2FtZXVz
 ZXIsb3U9RFNBTUUgVXNlcnMsZGM9ZXhhbXBsZSxkYz1jb20iIGNyZWF0aW9uZGF0ZT0iMTQwOTg5NjY
 3NjM4MiIgbGFzdG1vZGlmaWVkZGF0ZT0iMTQwOTg5NjY3NjM4MiIgcmVmZXJyYWxQb2xpY3k9ImZhbH
 NlIiBhY3RpdmU9InRydWUiID4KPFJ1bGUgbmFtZT0idXNlci1yZWFkLXJ1bGUiPgo8U2VydmljZU5hb
 WUgbmFtZT0ic3VuQU1EZWxlZ2F0aW9uU2VydmljZSIgLz4KPFJlc291cmNlTmFtZSBuYW1lPSJzbXM6
 Ly8qZGM9ZXhhbXBsZSxkYz1jb20vc3VuSWRlbnRpdHlSZXBvc2l0b3J5U2VydmljZS8xLjAvYXBwbGl
 jYXRpb24vKiIgLz4KPEF0dHJpYnV0ZVZhbHVlUGFpcj4KPEF0dHJpYnV0ZSBuYW1lPSJNT0RJRlkiIC
 8+CjxWYWx1ZT5hbGxvdzwvVmFsdWU+CjwvQXR0cmlidXRlVmFsdWVQYWlyPgo8L1J1bGU+CjxTdWJqZ
 WN0cyBuYW1lPSJTdWJqZWN0cyIgZGVzY3JpcHRpb249IiI+CjxTdWJqZWN0IG5hbWU9ImRlbGVnYXRp
 b24tc3ViamVjdCIgdHlwZT0iQXV0aGVudGljYXRlZFVzZXJzIiBpbmNsdWRlVHlwZT0iaW5jbHVzaXZ
 lIj4KPC9TdWJqZWN0Pgo8L1N1YmplY3RzPgo8Q29uZGl0aW9ucyBuYW1lPSJBdHRyQ29uZGl0aW9uIi
 BkZXNjcmlwdGlvbj0iIj4KPENvbmRpdGlvbiBuYW1lPSJjb25kaXRpb24iIHR5cGU9IlVzZXJTZWxmQ
 2hlY2tDb25kaXRpb24iPgo8QXR0cmlidXRlVmFsdWVQYWlyPjxBdHRyaWJ1dGUgbmFtZT0iYXR0cmli
 dXRlcyIvPjxWYWx1ZT5naXZlbm5hbWU8L1ZhbHVlPjxWYWx1ZT5zbjwvVmFsdWU+PFZhbHVlPmNuPC9
 WYWx1ZT48VmFsdWU+dXNlcnBhc3N3b3JkPC9WYWx1ZT48VmFsdWU+bWFpbDwvVmFsdWU+PFZhbHVlPn
 RlbGVwaG9uZW51bWJlcjwvVmFsdWU+PFZhbHVlPnBvc3RhbGFkZHJlc3M8L1ZhbHVlPjxWYWx1ZT5wc
 mVmZXJyZWRsb2NhbGU8L1ZhbHVlPjxWYWx1ZT5pcGxhbmV0LWFtLXVzZXItcGFzc3dvcmQtcmVzZXQt
 b3B0aW9uczwvVmFsdWU+PFZhbHVlPmlwbGFuZXQtYW0tdXNlci1wYXNzd29yZC1yZXNldC1xdWVzdGl
 vbi1hbnN3ZXI8L1ZhbHVlPjxWYWx1ZT5kZXNjcmlwdGlvbjwvVmFsdWU+PFZhbHVlPnN1bklkZW50aX
 R5U2VydmVyRGV2aWNlS2V5VmFsdWU8L1ZhbHVlPjxWYWx1ZT5zdW5JZGVudGl0eVNlcnZlckRldmljZ
 VN0YXR1czwvVmFsdWU+CjwvQXR0cmlidXRlVmFsdWVQYWlyPgo8L0NvbmRpdGlvbj4KPC9Db25kaXRp
 b25zPgo8L1BvbGljeT4=
sunsmspriority: 0

dn: ou=SelfWriteAttributes,ou=default,ou=default,ou=OrganizationConfig,ou=1.0,ou
 =sunEntitlementIndexes,ou=services,o=sunamhiddenrealmdelegationservicepermissio
 ns,ou=services,dc=example,dc=com
ou: 1409896676382=lastmodifieddate
ou: application=sunAMDelegationService
ou: lastmodifiedby=cn=dsameuser,ou=DSAME Users,dc=example,dc=com
ou: name=SelfWriteAttributes
ou: 1409896676382=creationdate
ou: |1409896676382=creationdate
ou: createdby=cn=dsameuser,ou=DSAME Users,dc=example,dc=com
ou: |1409896676382=lastmodifieddate
ou: SelfWriteAttributes
objectClass: organizationalUnit
objectClass: sunServiceComponent
objectClass: top
sunserviceID: indexes
sunKeyValue: serializable={"creationDate":1409896676382,"policyName":"SelfWriteA
 ttributes","createdBy":"cn=dsameuser,ou=DSAME Users,dc=example,dc=com","name":"
 SelfWriteAttributes","lastModifiedBy":"cn=dsameuser,ou=DSAME Users,dc=example,d
 c=com","eSubject":{"state":"{\n  \"className\": \"com.sun.identity.policy.plugi
 ns.AuthenticatedUsers\",\n  \"exclusive\": false,\n  \"name\": \"delegation-sub
 ject\",\n  \"values\": []\n}","className":"com.sun.identity.entitlement.opensso
 .PolicySubject"},"lastModifiedDate":1409896676382,"active":"true","className":"
 com.sun.identity.entitlement.opensso.OpenSSOPrivilege","eCondition":{"state":"{
 \n  \"className\": \"com.sun.identity.policy.plugins.UserSelfCheckCondition\",\
 n  \"name\": \"condition\",\n  \"properties\": {\"attributes\": [\n    \"givenn
 ame\",\n    \"sn\",\n    \"cn\",\n    \"userpassword\",\n    \"mail\",\n    \"t
 elephonenumber\",\n    \"postaladdress\",\n    \"preferredlocale\",\n    \"ipla
 net-am-user-password-reset-options\",\n    \"iplanet-am-user-password-reset-que
 stion-answer\",\n    \"description\",\n    \"sunIdentityServerDeviceKeyValue\",
 \n    \"sunIdentityServerDeviceStatus\"\n  ]}\n}","className":"com.sun.identity
 .entitlement.opensso.PolicyCondition"},"entitlement":{"actionsValues":{"MODIFY"
 :true},"applicationName":"sunAMDelegationService","name":"user-read-rule","reso
 urceNames":["sms://*dc=example,dc=com/sunIdentityRepositoryService/1.0/applicat
 ion/*"]}}
sunxmlKeyValue: pathparentindex=/sunidentityrepositoryservice/1.0
sunxmlKeyValue: pathparentindex=/sunidentityrepositoryservice
sunxmlKeyValue: pathparentindex=/sunidentityrepositoryservice/1.0/application
sunxmlKeyValue: hostindex=://dc=example,dc=com
sunxmlKeyValue: pathparentindex=/
sunxmlKeyValue: pathindex=/sunidentityrepositoryservice/1.0/application
sunxmlKeyValue: subjectindex=identity:=all

```

`iPlanetAMPolicyService`のsunKeyValueをbase64デコードして<Value></Value>のペアにカスタム属性を追加する。
たぶんエンコードしなおして保存すればOK.

`sunEntitlementIndexes`のsunKeyValueのselfwriteが可能なリストの最後に\n \"customAttribute\"\nを追加する。

```
service tomcat6 restart
```
で変更を反映させる。
これが出来ればpwmいらないといえばいらない。
社内の他のユーザの検索とかをしたいとかはたぶん内と思うけど。
pwmはpwmで不安定で微妙なところもあるのでOpenAMでまかなえるならそうしたい。
今後のアップデートも含めてOpenAMの方が安定しているだろうし。
インターフェースはOpenAM丸出しだと違和感があるのでユーザ情報編集画面だけでもGoogle AppsもしくはManagedであることが分かるインターフェースに出来るといいと思う。

Google Apps SSOを介さないで直接Googleのパスワードを問い合わせに行くアプリ、例えばweb画面を使わないアプリなどはOpenDJの変更と同時にGoogle Appsもprovisioningしないといけない。
OpenIDMのGoogle Apps Connectorを使えばOpenDJをリアルタイムにプロビジョン出来そうなので使ってみよう。

## 冗長化

### Requirement 
- Apache(LB)
- OpenAM2インスタンス

### Install

- １台目のインスタンスは上記通りに普通にインストールする。ロードバランサの設定をするのは２台目から。
- Apacheのインストール

```
yum install httpd mod_ssl
```

- Apacheのロードバランサ化

以下のホスト等は適宜置換。

```/etc/httpd/conf.d/virtualhost.conf
<VirtualHost *:80>
    ServerName "lb.example.com"
    ProxyRequests off
    ProxyPreserveHost on

    <Proxy *>
        order deny,allow
        Allow from all
    </Proxy>

    <Proxy balancer://opensso>
        BalancerMember http://openam-test.example.com:8080 retry=300 route=server1
        BalancerMember http://opendj-test2.example.com:8080 retry=300 route=server2
        ProxySet lbmethod=byrequests
        ProxySet stickysession=APLBCOOKIE
    </Proxy>

    Header add Set-Cookie "APLBCOOKIE=APACHE.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED

    ProxyPass /       balancer://opensso/

    ProxyPassReverse / http://openam-test.example.com:8080/
    ProxyPassReverse / http://opendj-test2.example.com:8080/

</VirtualHost>
```

2台目のインスタンスはインストール時に既存のサイトに追加するようにする。
既存の配備に追加で既に存在するOpenAMのURLを入力する。

```
サイト名: test
ロードバランサのURL: http://lb.example.com:80/openam
```


自動的に設定が埋まるので「次へ」を押す。
サイト名、ロードバランサのURLを入力しインストールを進める。ここで失敗が間違っていてもログイン後「設定」→「サーバーおよびサイト」より設定を直せるので問題ない。
インストールが終了したら各インスタンスへログインし「設定」→「サーバーおよびサイト」より親サイトの箇所が空欄になっているホストの親ホストを設定したサイトに変更する。