Azure AD を IdP として利用する

# はじめに
* 本記事では、Microsoft 社の「Azure Active Directory」(以後、Azure AD) を SAML の IdP として利用する際の簡易な設定方法を記載します。

# SAML とは
* 「SAML (Security Assertion Markup Language) 」は、異なるドメイン間で認証情報を連携することで、「フェデレーション」方式の「シングルサインオン」(以後、SSO) を実現する標準仕様です。
* OASIS が制定し、2.0 が最新バージョンです。
* また、SAML では「Assertion（アサーション）」と呼ばれる、XML 形式のメッセージを扱います。
    * Assertion では、ユーザの認証情報、属性、認可されたユーザの権限といった情報を含みます。

## シングルサインオンとは
* 1度のユーザ認証で複数サービスを利用できるようにする仕組みを「シングルサインオン」(以後、SSO) と呼びます。
* 近年は、異なるドメイン間の複数クラウドサービスに対して SSO をするために、ユーザの認証情報を連携する「フェデレーション」方式が利用されています。
    * なお、フェデレーション方式では、SAML 以外に「Open ID Connect」といった標準仕様が利用されています。

### SP、IdP とは
* SAML では、認証情報を要求するサービスを「Service Provider」(以後、SP)、認証を行うプロバイダーを「Identity Provider」(以後、IdP) と呼びます。
* SAML の認証フローでは、IdP のユーザ認証情報を、各 SP に連携することでシングルサインオンを実現します。
* また、以下の2種類のフローがあります。
    * 「Idp-Initiated」
       * ユーザが 最初に Idp に接続するフロー
         * IdP でユーザを認証し、SP への接続時に認証情報を連携する。

    * 「SP-Initiated」
        * ユーザが 最初に SP に接続するフロー
          * ユーザが SP に接続後、リダイレクト先の IdP でユーザを認証する。その後、認証情報を SP に連携する。

![IdP-initiated.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672573/336fe937-9aa1-3624-3e59-5bcffe50869c.jpeg)
![SP-initiated.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672573/da546aa0-122b-fd5b-93e8-e81ddfcbfb0c.jpeg)

### metadata とは
* SAML 認証を行う上で、各パーティー（IdP、SP）の情報を XML ベースの
  スキーマファイルに定義します。このスキーマファイルを「metadata」と呼びます。
* また、各パーティーの「metadata」を交換することで、信頼関係を構築します。
* なお、「metadata」では、以下の情報等が定義されます。
    * 各パーティーのエンドポイント
    * Binding
        * HTTP 通信時にメッセージをどのように送信するかの定義。代表例として以下がある。
            * HTTP Redirect Binding 
            * HTTP POST Binding
    * entity ID
        * 各パーティの識別子。
    * Name ID Format
        * 認証ユーザの識別子（Name ID）に対するデータフォーマット。

# Azure AD を IdP として利用する
以下では、Azure AD を IdP として利用し、SAML 認証する際の設定イメージを記載します。

## Azure AD 上の設定
### SP の構成例
例として、SP が以下の構成とします。

|種類|URL|備考|
|---|---|---|
|ログイン URL|https://saml.ex.com/sp|ユーザが SP にアクセスする際の URL|
|応答 URL（Assertion Consumer Service URL）|https://saml.ex.com/sp/response|IdP の認証情報を連携する、SP のリクエスト先 URL を指定します。|

### アプリケーションの作成
Azure AD の「エンタープライズアプリケーション」で以下メニューより、アプリケーションを作成します。なお、SP は、ギャラリーにないアプリケーションを想定しています。

* 「新しいアプリケーション」
  * 「独自のアプリケーションの作成」

### ユーザの割り当て
作成したアプリケーションで、以下メニューから SAML 認証する、Azure AD ユーザを割り当てます。なお、利用している Azure AD のプラン次第では、グループ単位での割り当ても可能です。

* ユーザーとグループ

### SAML 構成の設定
SAML の構成情報を設定します。

1. 対象メニューを開きます。
    * 「シングルサインオン」
        * シングル サインオン方式の選択
           * SAML
2. 「基本的な SAML 構成」を設定します。今回は必須項目のみを対象とします。
    * 識別子 (エンティティ ID)
      * SP の識別子を設定します。例えば、SP の ログイン URL とします。
    * 応答 URL
      * IdP のユーザ認証情報を連携する、SP の応答 URL を指定します。
3. 「ユーザー属性とクレーム」で、対象ユーザの識別子（NameID）等を必要に応じて設定します。今回は、デフォルトのままとします。
    * デフォルトでは、Name ID Format では「電子メールアドレス(emailAddress)」が指定されています。
    * また、Name ID として、Azure AD ユーザの「userPrincipalName」の属性値を参照します。

4. 「SAML 署名証明書」から SP 側に配置する証明書を取得できます。
    * SP で、IdP から送信される SAML Assertion（SAML Response）の署名を検証するための証明書を取得できます。

5. 「【アプリケーション名】のセットアップ」を参照し、SP 側で信頼関係を構築する IdP の情報を登録する際に利用します。
    * IdP のログイン URL、識別子（entity ID）、ログアウト URL が表示されます。

6. 「【アプリケーション名】でシングル サインオンをTest」では、SAML 認証時の動作をテストできます。

# SAML 認証の実行例（SP-initiated）
以下では、SP-initiated による SAML 認証の動作イメージを記載しています。
また、SAML Response のイメージは、ブラウザの拡張機能「[SAML-tracer](https://addons.mozilla.org/ja/firefox/addon/saml-tracer/)」の参照結果をもとにしています。

1. SP の ログイン URL（例. https://saml.ex.com ）にアクセスします。
2. IdP である Azure AD にリダイレクトされ、ユーザ認証画面が表示されます。
![IdP.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672573/04836324-78e4-1bc6-095e-b16fff9e967e.jpeg)

3. ユーザ認証後は、IdP から SP の 応答 URL （例. https://saml.ex.com/sp/response ）に転送されます。また、以下のような SAML Reponse を送信しています。

<details><summary>SAML Reponse(イメージ)</summary><div>

```
<samlp:Response ID="..." Version="2.0" IssueInstant="..." Destination="【SP の応答 URL】" InResponseTo="..." xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
  <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">【IdP の entity ID】</Issuer>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
  </samlp:Status>
  <Assertion ID="..." IssueInstant="..." Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
    <Issuer>【IdP の entity ID】</Issuer>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    ...
    </Signature>
    <Subject>
      <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">【ユーザの Name ID (例.userPrincipalName)】</NameID>
      <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <SubjectConfirmationData InResponseTo="..." NotOnOrAfter="..." Recipient="【SP の応答 URL】" />
      </SubjectConfirmation>
    </Subject>
    ...
    <AttributeStatement>
    ...
    </AttributeStatement>
    ...
  </Assertion>
</samlp:Response>
```
</div></details>
4. SP で SAML Response の検証後に、ユーザがサービスを利用できます。

# 参考情報
* http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
* https://qiita.com/Shinya-Yamaguchi/items/ee2c1ee4660bc75cf235