AD FS と Office 365 (Microsoft 365) をフェデレーション関係を結んだ時に監視対象となるフェデレーション メタデータは何なのか確認してみた。

#はじめに
AD FS と Office 365 (Microsoft 365) を下記 Microsoft の公開情報に記載の手順 (Convert-MsolDomainToFederated) もしくは Azure AD Connect を使って AD FS とフェデレーション関係を結んだ場合、AD FS が IdP (トークンを発行する側) となり Office 365 が RP (サインインする側) になりますが、この場合は WS-Federation プロトコルを利用して認証が行われます。

(実際には AD FS が発行する SAML 1.1 規格のトークンをユーザーが受け取った後に Azure AD に提示して Azure AD から発行される  OpenID Connect の ID トークンを利用して Office 365 にサインインします。)

[シングルサインオン用に Office 365 用 ADFS をセットアップする](https://docs.microsoft.com/ja-jp/office365/troubleshoot/active-directory/set-up-adfs-for-single-sign-on)

上記 Convert-MsolDomainToFederated コマンドレットなどで AD FS と Office 365 でフェデレーション関係を結ぶと、AD FS の「証明書利用者信頼」に「Microsoft Office 365 Identity Platform」として必要な構成が自動的に構成されます。

そして下記画面ショットのように証明書利用者信頼のフェデレーション メタデータが「証明書利用者を監視する」にチェックが入った状態で監視対象となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/dcaf64f6-0e5f-28d2-7b8e-a45d88707431.png)

下記 URL が監視対象のフェデレーション メタデータの実体 (リンクをクリックすると XML 形式のメタデータ中身が見られます)ですが、このフェデレーション メタデータは RP として AD FS とフェデレーション関係を結んでいる Azure AD のフェデレーション メタデータになります。

Azure AD フェデレーション メタデータ
https://nexus.microsoftonline-p.com/federationmetadata/2007-06/federationmetadata.xml

後日、この Azure AD フェデレーション メタデータの更新に関する公式 Blog を書く予定ですが、この Azure AD フェデレーション メタデータ内の証明書や署名の情報は AD FS と Office 365 のフェデレーション認証において利用されているのかどうか気になりました。

答えは、上記 Convert-MsolDomainToFederated コマンドレットなどで AD FS と Office 365 でフェデレーション関係を結んだ WS-Federation 認証の場合において、この Azure AD フェデレーション メタデータは利用されないことが分かりました。

公式 Blog を書くために自分自身が理解する必要があり、この件について調べ始めました。
Office 365 から SAML Request を要求する際に、AD FS 側は SAML Request に署名していることを要求するか、署名しなくても Request を受け入れるかパラメーターで決められますが、Convert-MsolDomainToFederated コマンドレットや Azure AD Connect などで Office 365 との WS-Federation 関係を結んだ場合においては既定で SAML Request 時に Office 365 からの署名は要求しないことが分かりました。

また、検証を色々やる中で結果的に完全に蛇足になってしまいましたが、AD FS が SAML Response (SAML トークン) を発行する場合には AD FS サーバーが持っている秘密鍵で署名を行い、AD FS サーバー上で構成しているトークン署名証明書内に含まれる公開鍵を利用して SAML Response の中身を検証しますが、この SAML Response の検証に利用する公開鍵の抽出を過去に自分が行った手順を基に試してみました。

AD FS サーバーの「証明書利用者信頼」の「Microsoft Office 365 Identity Platform」の中にフェデレーション メタデータの URL が書いてあるので、さもこのフェデレーション メタデータが使われるように見えますが、実体は Azure AD のフェデレーション メタデータであり Office 365 が SAML Request する時に利用するもので、且つ既定では SAML Request 時に署名は不要のため、少なくとも署名やトークンの中身を検証する場合においては使われていないのではという結論に至りました。

#記事にまとめるまでに参照した情報の一覧
[電子署名の基礎知識](https://qiita.com/angel_p_57/items/437ca6235defc938b97d)
[SSL/TLSの基本](https://qiita.com/angel_p_57/items/446130934b425d90f89d)
[プロトコルから見るID連携](https://www.slideshare.net/naohiro.fujie/id-42157018)
[ADFSトレーニングテキスト全文公開チャレンジ(8) – ADFSのコンポーネント](https://azuread.net/archives/10432)
[Active Directory Federation Service - Office365](https://www.youtube.com/watch?v=--KiPF5_ZSo) ※英語の動画ですが基本動作を押さえられます。

Microsoft 公開情報
[Understanding WS-Federation](https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/bb498017(v=msdn.10)?redirectedfrom=MSDN)
[AD FS のトラブルシューティング-Fiddler-WS-Federation](https://docs.microsoft.com/ja-jp/windows-server/identity/ad-fs/troubleshooting/ad-fs-tshoot-fiddler-ws-fed)
[シングルサインオン用に Office 365 用 ADFS をセットアップする](https://docs.microsoft.com/ja-jp/office365/troubleshoot/active-directory/set-up-adfs-for-single-sign-on)
[ADFS Deep-Dive: Comparing WS-Fed, SAML, and OAuth](https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/adfs-deep-dive-comparing-ws-fed-saml-and-oauth/ba-p/257584)

#やってみる
#####1.AD FS と Office 365 が WS-Federation プロトコルを利用して認証しており、SAML Request 時の署名を要求しない設定になっていることを確認する

まず、AD FS と Office 365 が WS-Federation でフェデレーション関係を結んでいることを確認する方法ですが、
AD FS サーバーの「Windows 管理ツール」→「AD FS の管理」→「証明書利用者信頼」の順に選択して表示される「Microsoft Office 365 Identity Platform」を右クリックし、「プロパティ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/66751ceb-70c7-554d-5d37-17865f47da8a.png)

プロパティ画面内の「エンドポイント」タブを選択すると表示される下記画面ショットに書かれている通り、「WS-Federation のパッシブ エンドポイント」とかかれていますので、WS-Federation プロトコルだけを利用していることが分かります。
下記に書いてある URL が Office 365 側に AD FS が発行したトークンを渡す先になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/c1e8caf2-fed0-9d13-9244-fe1f050a57fe.png)

Office 365 とは異なる SaaS アプリと AD FS を SAML 連携しているアプリの「エンドポイント」を見ると分かりますが、こちらは SAML プロトコルを利用していることが分かります。(意図的にフェデレーション メタデータを交換して SAML 連携させています。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/345353be-c7a5-bf05-a3d1-79b15307db15.png)

PowerShell で確認する場合は、以下コマンドレットで確認できます。

```powershell

connect-msolservice
Get-MsolFederationProperty -DomainName <ドメイン名>
```


下記が実行結果ですが、AD FS と Microsoft Office 365 との間では既定で WS-Federation (WsFed) が利用されていることが確認できます。
SAML を利用している場合は SAMLP と表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/ef602f22-fdc3-6754-8031-42bff79239a2.png)

次に、AD FS と Office 365 の間において Office 365 側から要求する SAML Request には署名を要求していないことを確認します。
確認方法としては、同じ PowerShell プロンプト上で「Get-ADFSRelyingPartyTrust -Name "Microsoft Office 365 Identity Platform"」と実行することで確認ができます。

以下画面ショットのように「SignedSamlRequestsRequired」の値が「False」となっている場合には、RP (今回の場合は Office 365) から SAML Request を要求する際に Office 365 からの署名を要求しない、ことを意味します。
逆に下記公開情報に記載があるとおり「True」となっている場合は SAML Request に署名が含まれていないと AD FS 側で SAML Request を破棄する動作になるようです。
(破棄する動作を確認したかったのですが再現できず断念しました…)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/0de268d1-7358-ed79-53a4-3b05c938539c.png)

[Set-AdfsRelyingPartyTrust](https://docs.microsoft.com/en-us/powershell/module/adfs/set-adfsrelyingpartytrust?view=win10-ps)

>-SignedSamlRequestsRequired
**Indicates whether the Federation Service requires signed SAML protocol requests from the relying party. If you specify a value of $True, the Federation Service rejects unsigned SAML protocol requests.**
Type:	Boolean
Position:	Named
Default value:	None
Accept pipeline input:	False
Accept wildcard characters:	False

以上のことから、AD FS と Office 365 間で WS-Federation を結んでいる場合、Azure AD フェデレーション メタデータは少なくとも署名用途や検証に使う証明書内の公開鍵などは利用されないと判断できるかと思います。

#####2.AD FS が発行する SAML Response (SAML トークン) 内に使われているトークン署名証明書の公開鍵を抽出する(完全に蛇足)
AD FS が発行する SAML Response に署名するのは AD FS が秘密鍵で署名をしてトークン署名証明書内の公開鍵を利用して検証するということは明らかではありますが、蛇足情報として SAML Response 内の公開鍵を抽出してみました。

AD FS が発行する SAML Response から検証に利用する公開鍵を抽出する手順は過去に私自身が試した以下内容に沿って行いました。
[SAML Response の x.509 電子署名から公開鍵を取り出してみる。](https://qiita.com/Shinya-Yamaguchi/items/383a73e890d638666935)

実際に叩いたコマンドは以下 2 行だけです。

```powershell
PowerShell 上で実行
certutil -decode x509.txt x509.der
         
Linux OS 上で実行
openssl x509 -pubkey -noout -inform DER -in x509.der
```

Fiddler を起動した状態でブラウザーを利用してフェデレーション ドメインを持つユーザーで Office 365 (www.office.com) にサインインすると、AD FS の認証画面 (下記はフォーム認証) にリダイレクトされますので、資格情報を入力して Office 365 までサインインするまでの一連の作業を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/9e713e2d-b63d-c13a-ebb4-2083e0f5f1a4.png)

test003 で Office 365 にサインインしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/7e9b841d-9f77-c92d-2f99-8f6838541861.png)

Fiddler のインストールと HTTPS 通信を可読するために必要な設定は下記が参考になるかと思います。
[AD FS のトラブルシューティング-Fiddler](https://docs.microsoft.com/ja-jp/windows-server/identity/ad-fs/troubleshooting/ad-fs-tshoot-fiddler)

Fiddler を取得し、下記画面ショットのように AD FS が発行している トークン Response の欄を右クリックし、「Send to TextWizard」をクリックすると AD FS が発行したトークンの中身を参照できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/1e8523c1-5314-522a-689a-e8195b4ee844.png)

AD FS が発行したトークンの中で、下記 x509 証明書の部分だけを抽出します。
(一部中抜きしてますが、実際に動作を確認する時は、X509Certificateタグ内の値をスペースを含めないように抽出します。)

```xml

<X509Certificate>
MIIC3DCCAcSgAwIBAgIQao7tzI7qCqVEZPU27+2i/TANBgkqhkiG9w0BAQsFADAqMSgwJgYDVQQDEx9BREZTIFNpZ25pbmcgLSBzdHMuc2h5YW1hZy53b3JrMB4XDTIxMDEwMzE1MDY1M1oXDTI<中略>OxGXZicvDpVaGGZbAYfP4GsvpOAjWj0N1VTDFWFU0tlUtZ2vZiNWl8VKkyoyXPMGyAwekcKmeI87FdpHxdTBlv+T+jOFWyHuZKiLroH+nZfH5hNHBu04Ci6N9zqL8A0OA4ozeApgvRR5x7rJYuT5J60rRq4NbMYgFLvggcwU6iUzk4/OP2Gawygm/pGusXM70sAWSOg5gg==
</X509Certificate>
```

上記「SAML Response の x.509 電子署名から公開鍵を取り出してみる」に書かれている手順のとおり、証明書の中身だけをファイルとして保存します。

PowerShell を起動し、保存したディレクトリ上で下記コマンドレットを実行すると、サーバー証明書が作成されます。

```powershell
PS C:\> certutil -decode x509.txt x509.der
入力長 = 984
出力長 = 736
CertUtil: -decode コマンドは正常に完了しました。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/fb2c2031-f8e4-5aba-5e7a-61d4157a68aa.png)

サーバー証明書の中身を見ると、発行者が「ADFS Signing」と書かれており、AD FS が発行する**トークン署名証明書** であることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373423/aa39de61-a78b-b598-395b-e344eaf8d770.png)

X509 証明書から公開鍵を抽出するには openssl コマンドレットが実行できる環境にて「openssl x509 -pubkey -noout -inform DER -in x509.der」と実行することで抽出ができます。

```bash

[root@shyamag-centos7 ~]# openssl x509 -pubkey -noout -inform DER -in x509.der
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6fu0OQrfYPl8FVbkjuSI
8m5rPSImGw+Zo1SQ8IBimmbpSQpyQhYqStgRs0CWvNkyDTKU9Jwbn0QzM+RHi9fr
K4qaMk0+LgizmcwHMPw9jazklgzADrO6BplW4iYwAkW6CbVYQMaSL21GWbvbovlN
DFNtxXostjzjudJjfRI5SwzD/VY1dpmLEuH7NuQg/5PJIgOjGAvdJVCr7Jao+r3e
BhWHfoMLmUT0bS3ZL75JzZeF6LQehk45/q/gEffMmUFEPYQB31bRoTBxxJO9assz
9BZ8sO3iQ0TQc/ezQjlSKI7BmfwCAPS5A5PWcy8rhGxq9xTFjspxmn432VrsrhYe
TQIDAQAB
-----END PUBLIC KEY-----
```

ブラウザー経由で渡された SAML Response がユーザーから RP (Office 365) 側にわたり、Office 365 側で SAML Response の中身をこの公開鍵を利用して検証を行い、要件を満たせば今度は Azure AD 側に認可コードと ID トークンをもらいにいくフローに遷移しますが、今回はここまでにしたいと思います。

#おわりに
今回は AD FS と Office 365 を Convert-MsolDomainToFederated コマンドレットなどで WS-Federation プロンプトを利用したフェデレーション関係を結んだ時に自動的に「監視」のタブに入れ込まれるメタデータが何なのかの確認と、この Azure AD フェデレーション メタデータが AD FS と Office 365 間のフェデレーション認証において使われているのかどうかを見ていきました。

実際に影響はあるのかどうかなど、もう少し踏み込んだ内容については公式 Blog として公開を予定しております。
今回は個人的にも理解を深めるために実際に設定内容を確認したり Fiddler で動きを見てみたりしましたが、少しでも今回の内容が参考になれば幸いです。