#SAML ~ Binding の 巻 ~
こんにちは、さみーです。
Digital Identity技術勉強会 #iddance Advent Calendar 2020
2020年になりすっかりなりを潜めていますが、DigitalIdentityに関する技術の勉強会である #iddance のアドカレやります。
こちらの14日目です。
すっかりID厨離れをしてしまっている今日この頃で新しいことはチョトワカラナイデスから、
昔話をします。SAMLです。
##OpenID TechNight vol.17 で SAML の話もされてましたね
2020年8月に開催された「OpenID TechNight vol.17 ~ with コロナ編」 にて、 「Safari (ITP) & Chrome (SameSite=Lax as default) が Federation に与える影響」 と題してnovさんがSAMLについてもお話しされてました。
Federationは、Assertionを元に行うが、
OpenIDでは、OPとRPバックチャネルの直接通信でAssertion(ID Token)をやり取り。
SAMLではAssertionをフロントチャネルでやり取り。
OpenID Connect / SAML 共に、「こちらが主流」と説明がありますが、あくまで主流なだけであって、OpenID Connect でも 主に使われている Authorization Code Flow では バックチャネルで Assertion をやりとりしますが、フロントチャネルでやりとりする Implicit Flow も存在します。同じように、SAMLもバックチャネルでやりとりする Artifact Binding とうものが存在したりします。
ということで、今回は SAML の Bindingについてのお話です。
##SAML Bindings
SAML Bindingsの仕様はこちらです。
Bindings for the OASIS Security Assertion Markup Language (SAML) V2.0
http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
色々ありますが、認証リクエスト/レスポンスで利用されるのは次の3つです。
- HTTP Rediret Binding
- HTTP POST Binding
- HTTP Artifact Binding
名前からイメージされる通りですが、それぞれのシーケンスをおさらいします。
###HTTP Redirect Binding
saml-bindings 3.4.5 Message Exchange より抜粋
赤で囲った部分が 認証リクエストで用いられる HTTP Redirect Binding、
青で囲った部分が 認証レスポンスで用いられる HTTP Redirect Bindingです。
この Binding は、OpenID Connect でいうところの Implicit Flow ですね。
###HTTP POST Binding
saml-bindings 3.5.5 Message Exchange より抜粋
赤で囲った部分が 認証リクエストで用いられる HTTP POST Binding、
青で囲った部分が 認証レスポンスで用いられる HTTP POST Bindingです。
この Binding は、HTTP Redirect Binding 同様、OpenID Connect でいうところの Implicit Flow 、
加えて response_mode
として OAuth 2.0 Form Post Response Mode を採用したものになります。
###HTTP Artifact Binding
saml-bindings 3.6.5 Message Exchange より抜粋
赤で囲った部分が 認証リクエストで用いられる HTTP Artifact Binding、
青で囲った部分が 認証レスポンスで用いられる HTTP Artifact Bindingです。
認証レスポンスに Artifact Bindingを使うのは、OpenID Connect でいうところの Authorization Code Flow ですね。
認証リクエストに Artifact Binding を使うのは、FAPI Part2 の Request object endpoint を使うのと同じ、といったところでしょうか。
※ SAMLで Artifact を解決するのは Service Provider(Requester) で、OpenID Connet (FAPI) で request_uri を解決するのは Authorization Servier(Responder) といった違いはあります。
まとめると
上で挙げた3つの Binding について、OpenID Connect の Flow と比較してまとめると下記の通りです。
Binding (SAML) | Flow (OpenID Connect) |
---|---|
HTTP Rediret Binding | Implicit Flow (response_type=id_token ) |
HTTP POST Binding | Implicit Flow (response_type=id_token )+ OAuth 2.0 Form Post Response Mode ( response_mode=form_post ) |
HTTP Artifact Binding (認証リクエスト時の利用) |
FAPI Part 2 Request object endpoint 利用 (request_uri=XXXX ) |
HTTP Artifact Binding (認証レスポンス時の利用) |
Authorization Code Flow (response_type=code ) |
##使うBindingを指定したい
OpenID Connect では、
- Implicit Flow を使いたい場合には
response_type=id_token
- POST で
id_token
を送りたい場合は更にresponse_mode=form_post
も指定
- POST で
- Authorization Code Flow を使いたい場合には
response_type=code
と、認証リクエストのパラメータで指定すれば良いですよね。
では、SAMLの場合はどうすれば、HTTP Redirect Binding、HTTP POST Binding、HTTP Artifact Binding をそれぞれ使えるのでしょう?
###認証レスポンスで使うBindingについて
認証レスポンスで使うBindingは、OpenID Connect と同じように、
SAMLの認証リクエストで送る <AuthnRequest>
電文の中で指定します。
指定する方法はいくつかありますが、例えば ProtocolBinding
属性で指定すると
指定した Binding にて認証レスポンスが返却されます。
その他の指定方法は saml-core 3.4 Authentication Request Protocol をご参照ください。
<samlp:AuthnRequest
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
[その他の属性省略]>
[AuthnRequest中の要素省略]
</samlp:AuthnRequest>
<samlp:AuthnRequest
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
[その他の属性省略]>
[AuthnRequest中の要素省略]
</samlp:AuthnRequest>
###認証リクエストで使うBindingについて
認証リクエストにて SAMLart
パラメータ名で Artifact を送れば、あとはIdP側で良いようにやってくれます。Artifact を解決する ArtifactResolutionService
は、もちろんSP側で準備ください。(saml-bindings 3.6.4 Artifact Format で記載のフォーマットのArtifactを送ります)
https://idp.example.com/SAML/SSO?SAMLart=[ここにArtifactを指定]&RelayState=XXXXXX
####Artifact Binding を使わない場合 との比較
ちなみに、Artifact Binding を使わない場合は SAMLRequest
パラメータに <AuthnRequest>
電文が指定されて送られます。(saml-bindings 3.4.4/3.5.4 Message Encoding で記載の通りにEncodeしたものを送ってます)
https://idp.example.com/SAML/SSO?SAMLRequest=[AuthnRequest電文]&RelayState=XXXXXX
##なぜ冒頭のように異なる主流を持つか
SAML も OpenID Connect も同じような Flow を持つにも関わらず、
なぜ 冒頭 のように、主流が異なるのでしょうか?
それは、その成り立ちに依ります。(←個人的見解です)
OpenID Connect は言うまでもなく OAuth 2.0 の上に構築された認証連携の仕様です。
その 元となる OAuth 2.0 のSecurity Best Current Practice(現状 Draft16) の 2.1.2. Implicit Grantの項目には
SHOULD NOT use the implicit grant
と記載があります。
OAuth 2.0 で Protected Resources へのアクセスのために使われる アクセストークン は ほぼ Bearerトークンとして利用されるものであるため、フロントチャネルを介する=不正なトークンの授受/利用がされてしまいかねず、脆弱であるといった理由からでしょう。
ここから、OpenID Connect も何となく Implicit Flow は避けたほうが良いというイメージになり(あるいは OAuth と合わせて使うことが多いため、Implicit Flow を避けるから?)
OpenID Connect といえば Authorization Code Flow、
すなわち、バックチャネルでAssertionをやりとりするのが主流となっているのではないでしょうか。
しかし、Assertion (id_token) は署名も付されており、
適切な検証がなされればフロントチャネルを介したからといって全く脆弱ではありません。
バックチャネルでのやりとりは単純に通信の回数が増えることから、
SAMLでは基本的にフロントチャネルでのやりとりを使っており、
電文のサイズが大きいなどの理由によりフロントチャネルでのやりとりが難しい場合に
Artifact Binding、すなわちバックチャネルでのやりとりを利用するという形を取っていたため
フロントチャネルでのやりとりが主流となっていると思われます。
温故知新
SAML の NameID Format について書いた際 にも触れましたが、
SAMLを活用するユースケースに、当時は時代があまり追いついてなかったような気がします。
先日 #idcon vol.28 DID特集その2 - その名も "#didcon" が開催され、
DIDの最新について、学ばせていただきましたが、
ふと、Liberty Alliance Day 2007 の パネル展示で行われていたデモを思い出しました。
かなりうろ覚えではありますが、
PCで使っているWebサービスにて認証が必要になった時に
携帯に立てられた SAML IdP が起動され、
携帯をポチポチっと操作したら、
PC上で認証が完了、継続してサービスを利用できる、
といったようなものだったと思います。
スマホというものがまだ世に出回っていないガラケーの時代に、
既に DID のようなものが実装されていた、というわけです。
SAMLって、やっぱり奥が深いですね。
まだまだ学ぶことが多そうです。