異なるActive Directory間の複数ADFS間連携（multiple AD FS federation）[1/3]

(2019.9.5初出,2019.9.14追記)
##1. はじめに
2019年にADFS vs ADFS連携という誰も見向きもしない恐れのある記事を書きます・・・

##2. やりたい事
2つの異なるADドメイン(BLUE社、YELLOW社)にそれぞれADFSを建て、ADFS間のフェデレーション連携をする。


![0101_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/dbb8ae82-9882-ec89-1c79-4710157a8841.png)

- BLUEドメイン(blue.com)と、YELLOWドメイン(yellow.net)のADFSでフェデレーション信頼関係を結ぶ
- 図中App はadfs.yellow.net上へ利用者信頼として登録する。adfs.yellow.net は adfs.blue.com 上へ利用者信頼として登録する
- adfs.yellow.netから見てadfs.blue.com は、要求プロバイダー信頼となる。
- BLUE側ADFSはID＆パスワード認証を行い、YELLOW側のADFSはYELLOW　ADの属性情報を取得し、アプリケーションへ渡す。ユーザーはYELLOWドメインの自分のパスワードを入力することはない（もっと言うとYELLOWのパスワードを知らなくてもこのシーケンスは成立する）
- ユーザーと端末はBLUEドメインに参加している事は必ずしも必須ではないが、もしBLUEドメインに参加している場合は統合Windows認証によりIDとパスワードの入力も不要となる
- YELLOW側ADFSでYELLOW側ADの属性情報を取得するには、Appの利用者信頼で手書きでカスタム属性取得を記述しないとできません

Appは何等かのASP.NET Webアプリケーションwith WS-Fererationでも、オンプレSharePoint、SAML2準拠Webアプリケーションなどを想定します。AppにYELLOW側属性情報はもちろん、BLUE側ADFSで取得した属性情報もセキュリティトークンとして渡すことができます。
![4.0_002mini.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/2058495c-c1fc-6d63-156f-72ef3a7f308a.png)


今回は上記のAD属性値に対し、以下をAppへ渡すこととします。
![4.0_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/dbb6bd3b-ea1d-fd74-79e6-05c64d188de3.png)

- 現実の設計上は、Appへ渡すのはYELLOW側ADの情報のみがあるべき姿かとおもいます（BLUEのAD情報を漏洩させてどうするよっていう
- Appに渡すYELLOW側AD情報も、最低限とするのが整った設計です（キリがないため。例えば、App ＝SharePointの場合ではYELLOW側ADとAppを密結合にしてその他際限ない属性情報は授受(YELLOW側ADとSharePointでFIM通信して)してもらう設計ですよね・・・)



##3. この投稿で説明しないこと
* ADFSそのものついて（ADFSってなに？、利用者信頼とは？FederationMetadataってなに？）
* ADFSとAzureAD連携（今回は複数のオンプレADFS間連携についての投稿です）
* SSL証明書の作成方法、AD CS によるプライベート証明書発行方法について

##4. 構成内容

4.1. BLUE側ADFSへFederationMetadataによりYELLOW側ADFSを利用者信頼(Relying Party)登録する
4.2. YELLOW側ADFSへFederationMetadataによりBLUE側ADFSを要求プロバイダー信頼(Claims Provider)として登録する
4.3. YELLOW側ADFSへAppを利用者信頼として登録する
4.4. 上記4.1.のBLUE上のYELLOW利用者信頼の要求規則(発行変換規則 Issuance Transform Rules)を作成する
4.5. 上記4.2.のYELLOW上のBLUE要求プロバイダー信頼の要求規則(受け付け変換規則Acceptance Transform Rules)を作成する
4.6. 上記4.3.のYELLOW上のApp利用者信頼の要求規則(発行変換規則 Issuance Transform Rules)を作成する
4.7. トークン内容をC#コンソールツール書いて確認する
4.8. その他

###4.1. BLUE側ADFSへFederationMetadataによりYELLOW側ADFSを利用者信頼登録する
BLUE側ADFSへ利用者信頼の新規追加ウィザードで、URL(https://adfs.yellow.net/federationmetadata/2007-06/federationmetadata.xml)を入力してによりYELLOW側ADFSを利用者信頼(Relying Party)登録する。手動で作成でも可、BLUEとYELLOWがネットワーク的に疎通しない環境であればFederationMetadata.xmlファイルをYELLOWからダウンロードして登録でも可。
![4.1_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/963236a6-359f-163b-9128-729cd081e2b7.png)


###4.2. YELLOW側ADFSへFederationMetadataによりBLUE側ADFSを要求プロバイダー信頼として登録する
前述4.1と似た操作ですが、今度は利用者信頼ではなく要求プロバイダー信頼へURL(https://adfs.blue.com/federationmetadata/2007-06/federationmetadata.xml)を入力し、BLUE側ADFSを要求プロバイダー信頼(Claims Provider)として登録する。
ADFS既定値ではActive Directoryのみだった要求プロバイダー信頼に、BLUEが追加される。

![4.2_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/fdd832d3-74d1-a271-0aa7-1fcbdd4c23c7.png)


###4.3. YELLOW側ADFSへAppを利用者信頼として登録する
YELLOW側ADFSへAppを利用者信頼として登録する。
画像は、Webアプリケーション側のPassive-EndPointが"https://www.yellow.net/rp/"、識別子が”urn:rp02”の例
![4.3_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/515605fc-20e2-1d8b-7f54-84502719842e.png)

###4.4. BLUE上のYELLOW利用者信頼の要求規則(発行変換規則)を作成する
上記4.1.のBLUE上のYELLOW利用者信頼の要求規則(発行変換規則 Issuance Transform Rules)を作成します。
ここで、BLUE ADFSからYELLOW ADFSへ、NameIDを渡さなければいけません。YELLOW　ADFS上でユーザーを一意に特定できるIDとなります。
ADFSなどのIDPを連携する場合のNameIDについてはSAMLで規定されています（Ws-Federation世界のRFCなどにもあるかもしれませんが）。
今回は、BLUE側ADのwwwhomepageという属性に便宜上(＝この属性だれもつかってないから使ったろ)、YELLOW側ADのuserPrincipalNameを
格納し、NameID名義で渡すことにします。


![4.0_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/65770a3d-1ae2-8f58-e45f-00d5442dc5d8.png)

BLUE側ADから属性情報を抽出するルールと、wwwhomepage属性をNameID型へセットするルールを記述します。
![4.4_001 _mini.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/c5f3be61-9300-3735-7d3c-a3c09350f67f.png)

ADから属性を取得します。wwwhomepageは、マイナーで重要度が低い属性のせいなのでしょう、ADFS要求記述上にないので、手入力でType名を入力します（もちろん、事前に要求記述にwwwwhomepageのためのtype記述を宣言してもよい）
![4.4_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/330850f9-2432-08a5-7e96-2d57418048d6.png)
この ↑ 図中のLDAP Attributeのプルダウンに出てくる属性は何？、Outgoingに出てくる属性は何？というとは（気力があれば）章末で記載します。

ちなみに、このGUIの要求記述は、CLIでは以下になります。

```
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
 => issue(store = "Active Directory", types = ("meowmeow", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"), query = ";wwwhomepage,userPrincipalName,mail;{0}", param = c.Value);
```

NameIDでの出力は以下
![4.4_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317326/2f1ffb09-3bee-0547-e07a-d706989ec8a7.png)
このGUIの要求記述は、CLIでは以下になります。

```
c:[Type == "meowmeow"]
 => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
```

１個目の要求記述GetDataFromBlueADで、wwwhomepage属性をピックアップして、（要求記述のプルダウンに無い属性なので）meowmeowという変数に逃がして
２個目の要求記述OutputNameIDでmeowmeow変数から、persistent属性を持つ、NameIDという型、タグに変換して送出するという流れになります。この辺のわからなさはとってもSAML2なようで、Microsoftの記事は見つけられせんでした。
OASISの[SAML2ドキュメント](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html)を読んでも心が折れるため、周辺記事を読むだけでした。

SAML2については、以下の記事が癒しです。
[SAML認証に関する自分なりのまとめ](https://nantonaku-shiawase.hatenablog.com/entry/2016/07/13/081053)


[2]へ続きます！