SAML ~ NameID Format をご紹介 ~

#SAML ~ NameID Format をご紹介 ~
<img width="450" alt="SAML2.0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246440/097ccec2-dd92-191b-86e4-5ec05d729205.png">

こんにちは、さみーです。

>[**Japan Digital Design Advent Calendar 2020**](https://adventar.org/calendars/5160)
>Japan Digital Design 社員有志 による Advent Calendar です。

:point_up_tone2:これの2日目です。

急遽書くことにしてしまったので、そんな時は、**SAML** に頼ります。

##疎遠になった仕様書
昔に比べると本当に便利になっていて、
SAML使いたい
→ 設定画面開く
→ ドキュメントの通りにぽちぽちする
→ 設定完了
→ SAML連携完了！
・・・すごい。すごすぎます。

SAML対応製品インストールして、証明書作って、Metadata組み立てて配置して、
製品の設定ファイルを設定して・・・そうやって連携先を構築していたのが懐かしいです。

恵まれていて羨ましいと思うその一方で、
簡単にできすぎるがゆえなのか、
仕様が複雑すぎて（使われていない部分が多すぎて）
詳しくは知らない（仕様書読む気が起きない）
という方が多いらしいですね。
仕様書を熟読する機会を与えられた私は幸せ者だったのでしょう。

ちなみにSAMLの仕様書は下記にあります
>OASIS SAML wiki
>https://wiki.oasis-open.org/security/FrontPage

##たくさんあるSAML仕様群

[OASIS SAML wiki](https://wiki.oasis-open.org/security/FrontPage) を見ても分かる通り、
SAMLとひとことに言っても、切り口はたくさんあるんですよね。
それこそ、Metadataって何？ Bindingって？
NameID Format？
Authentication Context？
Assertionの検証は何を確認してるの？
・・・などなど、盛りだくさん。

その中でも設定項目として目にすることの多い **NameID Format** について
ちょびっとお話しようと思います。

##NameID Format とは

NameID Format とは、その名の通り、NameID の Format です。
NameIDは、ざっくり言えば **対象ユーザーの識別子** なので、識別子としてどういったものを送っているか記す情報、といったところでしょうか。

SAMLの仕様では、[core](http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf) の **8.3 Name Identifier Format Identifiers** に、いくつか定義されているので以下に紹介します。

※ なお、下記の通り 省略/追加 しています。

+ **8.3.6. Entity Identifier** は、SAMLを扱うプロバイダの識別子についてのFormatであるため省略
+ **Encrypted Identifier** は、**8.3** には記載がないが、特別な値として **3.4.1.1 Element < NameIDPolicy >** に記載があるため追加

#### 8.3.1. Unspecified
+ `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified`
+ 実装依存
+ SAML仕様として定められていない独自のFormatを使う際に使われる
+ やり取りするIdPとSPの間で解釈できれば何でも良い

#### 8.3.2. Email Address
+ `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`
+ メールアドレス

#### 8.3.3. X.509 Subject Name
+ `urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName`
+ XML署名の<ds：X509SubjectName>要素

#### 8.3.4. Windows Domain Qualified Name
+ `urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName`
+ Windowsドメイン修飾名

#### 8.3.5. Kerberos Principal Name
+ `urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos`
+ Kerberosプリンシパル名

#### 8.3.7. Persistent Identifier
+ `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`
+ 永続識別子

#### 8.3.8. Transient Identifier
+ `urn:oasis:names:tc:SAML:2.0:nameid-format:transient`
+ 一時識別子

#### Encrypted Identifier 
+ `urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted`
+ 暗号化された識別子

##よく使われている NameID Format

設定画面を見たところ、GoogleやAzureADでは選択肢としてはある程度存在しますね。

<img width="300" alt="Google" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246440/d1165fb0-5827-a852-9c88-f912b720e498.png">　<img width="300" alt="Azure" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246440/b7ee3f0c-14f6-d28f-64d1-7d70626306a1.png">

とはいえ、よく使われるのは、`unspecified`、`email` あたりでしょうか。
ドキュメントに従って対象サービスの接続を設定する際に、
それ以外を指定させられたことは思いつく限りないんですよね。

`unspecified` としながら、実際の中身は `email` だったりすることも多いですね。

##Persistent と Transient

NameID Format を並べて見ると、毛色が違うものが気になると思います。
Encryptedはそもそも特殊なので置いておくと、`persistent` と `transient`。

しかしこの `persistent`（と `transient` ）こそ、SAMLの真髄ですよね。
いや、SAMLの真髄は、NameID Formatを自由に定められることのほうか。
（全て個人の感想です）

##「仮名」と呼ばれた PPID

認証連携を行うには、**誰の** 認証情報なのか、という情報、
すなわち **ユーザーの識別子** を連携する必要があります。

その連携のためだけに存在している識別子が、`presistent` `transient` です。

いわゆる、PPID、ですね。
紐づけのための識別子であり、
連携する2つシステムのユーザー識別子を再構築することは不可能なランダム文字列で構成されています。
「仮名」とか呼ばれてました。

同じユーザーを表す際には永続的に同じ識別子が使われるもの、が`persistent`。
`transient` は、同じユーザーを表す際にも都度変わってしまう一時的な識別子が使われます。

##なぜわざわざPPID？

これは言うまでもないですかね。

例えば、皆様よくご存知のマイナンバー。
それをキーにいろんな情報を名寄せされ個人の情報が一元管理されてしまう、
そうすると、あ〜んなことや、こ〜んなことまで、知られてしまうかもしれない、
それはいやだ！困る！！怖い！！！
ということを考慮してマイナンバーは
法律にて、扱える範囲が決められてますよね。

許されないけどできてしまう「名寄せ」を避けるため、
根本的に手段を断つ、それがPPID。
不必要にIDを共有するのはよろしくありません。

こうやって考えると、
ドキュメントに書かれているがまま設定していた **NameID Format**、
実はとても重要な設定項目だということが分かると同時に、
そこまで考えられていたSAMLに少し感動してしまいますよね。

##実は時代の先駆者だった SAML

昔のOpenID（Authentication 2.0）はどこでも使える「共通のID」というところから始まっているので、
「仮名」すなわちPPIDの概念はありませんでした。

OpenIDのほうが新しいしイケてる、と思われて、SAML is dead と良く言われます。
しかしそれは、その思想に時代が追いついてなかったところもあるのかな、
と思ったりする今日この頃です。

SAMLはとても奥が深いです。
ぜひ、故きを温めて新しきを知りましょう。

##追伸 ： ちなみに OIDC
ちなみに、OpenID Connectでは、「共通のID」の概念と、「PPID」の概念が共存するような考え方になっています。
許容された同一セクターでは、同一のPPIDを使う、といった感じでしょうか。
※詳しくは [Dynamic Client Registration 1.0](https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata) `sector_identifier_uri` 参照。