ラベル SAML の投稿を表示しています。 すべての投稿を表示
ラベル SAML の投稿を表示しています。 すべての投稿を表示

2024年9月30日月曜日

Ruby-SAMLの脆弱性(XML署名ラッピング攻撃)

こんにちは、富士榮です。

XML署名ラッピングによるRuby-SAMLの脆弱性が報告されていますね。


CVE-2024-45409としても登録されています。

内容としては割とオーソドックスなXML署名の実装の問題っぽいですね。

XML署名の特徴としてJWSとは違いドキュメント全体ではなく要素を指定して署名をおこなうことができる点、署名された値そのものも当該XMLの内部に埋め込まれることが挙げられます。
今回は部分的な署名を行うことができるという点について悪用された感じですね。上記の例で言うと、真ん中にあるalice@customer.comの値を含むid=dead[....]beefの部分に対して署名値が生成される一方で、攻撃者が偽の値をXML内に埋め込んだ同じid=dead[...]beefの部分は署名されない、ということが起きてしまうわけです。

この攻撃は2012年にJPCERTが以下のペーパーを出していたり、と過去もしばしば起きている話なので、実装する際は先人の知恵に頼りながらやっていけるといいでしょう。
参考)JPCERTの資料



2024年9月19日木曜日

SAMLerのためのOpenID Connect入門

こんにちは、富士榮です。

SAMLaiです。AIではありません。愛です。サムライです。


ということで、以前アナウンスさせていただいた大学ICT推進協議会(AXIES)の認証基盤部会主催の勉強会でSAMLを知っている人向けのOpenID Connect講座をやってきましたので資料をこちらにおいておきます。


もちろん一般企業などにも使える話だと思うので、ご覧ください。

2024年6月18日火曜日

京都大学 学術情報メディアセンターセミナー「デジタルIDの最新動向」でお話します

こんにちは、富士榮です。

来週6月25日に京都大学の学術情報メディアセンターでデジタルIDについてお話しさせていただきます。


告知・申込サイト

会場はもちろん京都大学ですが、ハイブリッド形式での開催となるのでリモート視聴も可能です。
旧来のSAMLをベースとしてアカデミックフェデレーションの話からOpenID Connectへの道筋の話や、学術機関におけるトラストフレームワークの今後の話、学位・学修歴などのデジタルクレデンシャルの利活用へのシナリオの話など、80分でまるっとお話ししようと思います。
ぜひご参加ください。

こちらがアジェンダです。

◆16時30分~16時35分 オープニング

◆16時35分~17時05分
講演者:清水 さや子(国立情報学研究所アーキテクチャ科学研究系 助教)
講演題目:Persistent IDの可能性とオンライン本人確認システムの紹介
講演概要:組織で提供されるIDは、通常、入学や採用時に発行され、卒業や離職時には無効化されます。そのため、所属組織が変更されると、その時点で、新しいIDを利用することになります。一方で、研究データ基盤サービスなど、所属組織の異動に関係なく継続利用が求められるサービスも存在します。このようなケースに対しては、オンラインでの本人確認を利用したスムーズなID移行が期待されています。本セッションでは、Persistent IDの活用や、スムーズにID移行を支援するためのオンライン本人確認システムについて紹介します。

◆17時05分~18時25分
講演者:富士榮 尚寛(伊藤忠テクノソリューションズ株式会社・みらい研究所長)
講演題目:学術機関におけるデジタルIDとトラストのこれから
講演概要:従来の学生や教員のアカウント管理や認証など、各種情報システムへのセキュアなアクセスを行うためのID管理・認証という世界観から、デジタル学修歴やデジタル学生証など新たなデジタルツールの利活用を行うためのデジタル・トラストをいかにして構築するか?が近年着目されています。本講演では従来のデジタルIDやトラストのあり方を踏まえた上で、今後のデジタル社会の発展に向けたデジタルIDとトラストのあり方について議論します。

◆18時25分~18時30分 クロージング




2024年5月20日月曜日

response_mode、”form_post"の実装

こんにちは、富士榮です。

EntraをはじめとするMicrosoftのIDスタックを使って開発をしていると必ずといっていいほど出てくるのがreponse_mode=form_postの壁です。特に非Microsoftのライブラリを使ってリライングパーティを開発する場合や、MicrosoftのIDスタックをリライングパーティとして非MicrosoftのIDaaSを構築する場合にはこのパラメータへの対応の有無で悩むことになります。

ということでresponse_modeって何?と言う話と自前でIdPを構築する際にform_postを実装する場合はどんな実装になるのか?を解説してみます。

response_modeとは?
OpenID Connect 1.0の仕様にはこのように定義されています。
OPTIONAL. Informs the Authorization Server of the mechanism to be used for returning parameters from the Authorization Endpoint. This use of this parameter is NOT RECOMMENDED when the Response Mode that would be requested is the default mode specified for the Response Type.

まぁ、元々はOAuth2.0のレスポンスの定義なので、こちらの仕様をみる方が適切といえそうです。

https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes

OPTIONAL. Informs the Authorization Server of the mechanism to be used for returning Authorization Response parameters from the Authorization Endpoint. This use of this parameter is NOT RECOMMENDED with a value that specifies the same Response Mode as the default Response Mode for the Response Type used. 

このOAuth2.0の仕様が発行されたのが2014年なのでその時点ではqueryとfragmentの2種類だけが本文には記載されており、追加モードとして今回の主役であるform_postの定義への参照が記載されています。


と、ここでちょっと待て、、と。

上記を見るとresponse_typeのデフォルトのresponse_modeの値を取る場合以外はこのパラメータを使うことは推奨しない、と明確に書いてありますね。

ということは、Azure AD B2Cが外部IdPと連携する際にresponse_typeの値に関わらずresponse_modeを必ず指定するのは推奨外の動作ってことですよね。。

また、先日書いたEntra IDの外部認証プロバイダ連携の場合はresponse_type=id_tokenでリクエストがされ、かつ外部認証プロバイダからはform_postでレスポンスが返されることを期待するにも関わらずresponse_modeが指定されないのはどうなんだ、、、という話です。(というか世の中にあるIdP製品やサービスでresponse_type=id_tokenだけをリクエストされてform_postでレスポンスするものは存在しないと思います)

この辺はMicrosoftさんちゃんと仕様を見ようよ・・・って思いますね。。

ちなみにresponse_type=id_tokenの場合のデフォルトのresponse_modeはfragmentです。(こちらに定義されています)

https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#id_token

The default Response Mode for this Response Type is the fragment encoding and the query encoding MUST NOT be used.


form_postとは?

気を取り直してresponse_mode=form_postの話に戻ります。response_modeは認可サーバからの認可レスポンスを返却するための方式を示すパラメータであることはわかりましたが、値にform_postが指定するというのはどう言うことなのか、についてはこちらの追加仕様に記載されています。

https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html

Abstractにこう記載されています。

This specification defines the Form Post Response Mode. In this mode, Authorization Response parameters are encoded as HTML form values that are auto-submitted in the User Agent, and thus are transmitted via the HTTP POST method to the Client, with the result parameters being encoded in the body using the application/x-www-form-urlencoded format.

まぁ、要するにHTML formにresponse情報を入れてredirect_uriにPOSTしますよ、ってことです。ws-federationやSAMLのHTTP POST Bindingですね。

ここでも話は横にそれますが、今でこそOAuth2.0やOpenID Connectは認可コードをリライングパーティに発行し、リライングパーティは認可サーバのTokenエンドポイントへ投げ込んでaccess_tokenやid_tokenを受け取る、いわゆるresponse_type=codeのコードフローが主流になっていますが、SAMLも当初はHTTP POSTやRedirect BindingではなくArtifact Bindingが主に使われていた時代がありました。当時はフィーチャーフォンのブラウザなど扱えるURL長に制限があったり、フロントに大きなPOSTデータを持ってくると通信量が増えてパフォーマンスに大きく影響が出るなどの問題があり、ArtifactといわれるコードをService Providerへ提供、Service ProviderがIdentity ProviderへSAMLトークンをとりにいく、という流れが必要だったためです。当時と今では事情がことなりますが、認可コードフローとのままですね。なんといってもOpenID Connectは、開発中はOpenID ABC(Artifact Binding and Connect)って名前でしたし、OpenID Connect Coreの定義をしている、OpenID FoundationのAB/ConnectワーキンググループはArtifact Binding Working GroupとConnect Working Groupから組成されており、ABはArtifact Bindingなわけです。


話を戻すと、Entra IDの外部認証プロバイダの際にも書いた通り、id_tokenとstateをformに乗せてPOSTしてあげるためのHTMLをレンダリングするコードを書けば良いってことになります。

node_expressとejsで書くとこんな感じです。

res.render("./form_post.ejs",
{
redirect_uri : req.body.redirect_uri,
id_token: id_token,
state: req.body.state
}
);

レンダリングされるhtmlテンプレートはこんな感じですね。(前回の記事では動きを見るために自動POSTしていませんでしたが、今回はJavaScriptで自動POSTする形にしています)

<html>
<head><title>Submit This Form</title></head>
<body onload="javascript:document.forms[0].submit()">
<form method="POST" action="<%= redirect_uri%>">
<input name="id_token" type="hidden" value="<%= id_token%>">
<input name="state" type="hidden" value="<%= state%>">
</form>
</body>
</html>


なぜform_postにこだわるのか?

しかし、form_postを使っているのって実態としてMicrosoftくらいしかいないんですよね・・・(Sign In with Appleも使ってたかも)

現状、ブラウザを経由してトークンのやり取りをする、つまりArtifactや認可コードを使わないパターンを使いたい大きな理由は先ほど挙げたフィーチャーフォンのブラウザの制限や通信速度・通信量の問題というよりも、エンタープライズなどIdPがファイアウォールの内側にありリライングパーティが外側にあるというケースやWalletがIdPになるケースなど、IdPが外部からのアクセスできない(Walletの場合はエンドポイントを持たない)という問題である場合が多いと思います。

その場合は当然Implicitを使う、つまりフラグメントにトークンを入れてJSでリライングパーティへ渡す、というやり方になるわけですが、これだとリライングパーティのredirect_uriがブラウザ上でJSをハンドリングする機能を実装することが前提になってしまいます。もちろんこれができるケースならば良いのですが、リライングパーティ向けの共通ライブラリを提供しようとすると単純にバックエンドでPOSTを受け取るAPIを作っておく方が楽なんじゃないかと思います。さらに言うと、これまでws-federationやSAMLのSP向けのライブラリを提供してきたベンダであれば少しパラメータを変えれば対応できると言う意味でform_postの方がありがたかった、と言うのが実情だったんだろうなぁ、、と聞いた話から推測しています(あくまで推測です)。まぁ、SameSiteの問題もあったりしますがこの辺は各社対応してきているので現状は大丈夫だと思いますが。


ということで、今回はresponse_modeとform_postの話をしましたが、みなさんが作るIDシステムやアプリケーションのシステム配置や要件によって適切な実装をしていきましょう。








2024年3月2日土曜日

なぜSAMLの脆弱性は今でも報告されるのか。そしてOIDCやVCは大丈夫なのか

こんにちは、富士榮です。

故Craig Burtonが”SAML is Dead”という名言を放ってから永らく経つわけですが、まだまだ現役のSAMLには今でもたまに脆弱性のレポートが出てきます。

* SAML is Dead


昨日もSilver SAML Attackに関するレポートが出ていました。

(図は記事より)

非常にざっくり要約すると、以下のようなことが書かれています。

  • 例としてEntra IDを挙げている
  • Entra IDではSAML Responseへの署名を行う秘密鍵として外部で生成した鍵を利用することができる(BYOK)
  • この鍵が漏洩するなどして不正に利用されるとSAML Responseの偽造ができてしまう
  • 署名に使う鍵はIDシステムの内部で発行したものを使った方が良い
当たり前じゃん。秘密鍵が奪われているんだから。

と言いつつ、何でこう言うことが起きるのかをちゃんと見ていきたいと思います。

脆弱性の原因

SAMLに限らず、ではありますがこの手の仕組みの基本は「デジタル署名を施したデータ(SAML AssertionやOpenID Connectにおけるid_tokenなど)」をIdentity ProviderからRelying Partyからの要求等に応じて送出する、という仕組みになっています。
こうなってくると当然のことながらデジタル署名を確実に実施・検証する、そして先日から順番に読んでいるOAuth2.0 Security Best Current Practiceにも要所要所でててくる、送信元・送信先をいかに限定するか、やり取りの過程の中でCSRFなど攻撃者によるインジェクションをいかにして防ぐか、などがポイントになってきます。
  • 署名・検証の不備を防ぐ
  • 通信過程における攻撃者の関与を防ぐ
後者についてはOAuth2.0 Security Best Current Practiceで見ていくとして、今回は先のSAMLの件もあるのでデジタル署名について見ていきたいと思います。

デジタル署名の前提

デジタル署名を安全に行うための前提は言うまでもなく署名に使う鍵を安全に管理すること、につきます(もちろんアルゴリズムの安全性の話は言うまでもありません)。
今回挙げたケースは鍵を適切に管理できない状態が起きると危ないですよ、というレポートなので、改めて秘密鍵の管理の重要性を説いています。
(もちろん、安全に管理してくださいね、と言ったところで安全に管理できない人たちが多いのは理解していますが、管理方法について深掘りするのはここでは避けます)

なお、今回は鍵管理の話にフォーカスが置かれていましたが、実際の脆弱性はデジタル署名する対象となるデータの生成に依存することが多いと思います。いわゆる「正規化」の問題です。

実際過去に当ブログでも紹介したDuo SecurityのレポートはSAML Assertionを生成する際のXMLの正規化がポイントでした。

正規化の問題

SAMLにおけるXMLは非常に柔軟なデータ表現である一方で「どうやって同一性を担保するか」という問題を抱えています。
例を挙げると、
  • 空白値のトリミング
    • <attribute name="email">test@example.jp</attribute>
    • <attribute name="email"> test@example.jp </attribute>
    • を同一のものとして扱うか
  • コメントの取り扱い
    • <!-- これはコメントです -->
    • <attribute name="email">test@example.jp</attribute>
    • <attribute name="email">test@example.jp</attribute>
    • を同一のものとして扱うか

    と言う問題です。
    これらを解決するために行われるのが「正規化」です。

    XMLの正規化はW3CのCanonical XML Version 2.0で定義されています。

    実際に正規化をする際はこの仕様に従いXMLを処理していくことになるのですが、この過程においてバグが混入することがある、というのが問題の原因になっています。
    実際、先に挙げたDuoのレポートでは値の間にコメントがあった場合の処理に問題があり、別のユーザで認証され生成されたSAML Assertionを使って別のユーザになりすますことができてしまう、というものでした。


    OIDCやVCではどうなのか?

    こう考えるとJSONを使うOpenID Connectや、JSONやJSON-LDを使うVerifiable Credentialsはどうなのか?という疑問が湧いてきます。

    まずOpenID Connectですが署名付きJSONトークンにはRFC7515 JWS(JSON Web Signature)を使っています。

    崎村さんが経緯をブログで紹介されていますが、SAMLの正規化との戦いの経験から「JWSでは正規化を行わない」のがポイントの一つになっています。

    Verifiable Credentialsについてはどうなのか、というとIETFのSD-JWT VCをパターンではOpenID Connectと同じくJWSなので正規化は行いません。
    しかしながらW3C VCはJSON-LDも許容するのでこちらは考えないといけません。JSON-LDはRDF(Resource Description Framework)に基づくLinked Dataを表現するフォーマットですので、正規化をするには、
    を使っていく必要があります。
    しかしながらこの正規化で使われるアルゴリズムであるUniversal RDF Dataset Normalization Algorithm 2015(URDNA-2015)をJSON-LDに適用する際の注意点についてレポートが上がっていたりしますので、実装者はかなり気を遣う必要がります。
    実際、昨年のIIWでもJSON-LDのプロパティ名を変えても署名が崩れないというデモ(Linked Dataの性質を考えると当然の動きではありましたが)もありましたが、VCとして使うにはこのようなことが起きないように注意深くデータ構造を設計する必要があります。

    しかし、この辺りの議論を見ているとJWSが「正規化を行わない」という判断をしたのは非常に重要なことだったことがわかりますね。


    2024年2月3日土曜日

    OpenID Providerを作る)仮名に加えて匿名をサポートする

    こんにちは、富士榮です。

    厳密にはOpenID Connectの仕様に定義されていませんが、以前実装したPairwise識別子(PPID)に加えて匿名の識別子(Transient Identifier)をサポートしたくなるシーンが存在するので、対応を入れていきたいと思います。

    その前にこれまでのおさらいです。


    識別子の種別、および仮名と匿名の違い

    識別子は主体を一意に特定するために利用される属性(群)を表しますが、名寄せのリスクなどに応じてどのような値を返すべきかについて十分な考慮が必要です。

    そもそも識別子には公開、仮名(かめい)、匿名の3種類が存在します。
    区分共有範囲OpenID Connectでの区分SAMLでの区分解説
    公開全体publicunspecifiedやemailaddress全RPに対して共通の識別子を送出する
    仮名RPpairwisepersistent特定のRPに対して一意の識別子を送出する
    匿名なし-transient毎回異なる識別子を送出する

    上記の表に示した通り、全てのRPに対して同じ識別子の値を送出するpublicなタイプ、同一のRPに対しては毎回同じ値を送出するPairwiseがOpenID Connectにおいては定義されています。ただし、特定のケースにおいて同一識別子出会ったとしても毎回送出する識別子を別のものに変えたい、というケースも存在します。SAMLにおいてはこのケースを想定してnameid-formatとしてpersistent(いわゆる仮名であるPairwise)に加えてtransient(匿名)を定義していました。
    ここで仮名と匿名の違いを正しく理解しておきましょう。
    • 仮名:連続性がある。つまり外野から見ると誰だか分からないが、特定のRPから見ると一意に主体を識別できる
    • 匿名:連続性がない。外野から見ても特定のRPから見ても一意に主体を識別することができない

    この辺りはかなり昔にイベントでしゃべった資料が出てきたので貼り付けておきます。


    実装してみる

    前置きが長くなりましたが、実装してみましょう。
    基本的にはpairwiseの中の種別として実装をしてみたいと思いますので、設定ファイルにスイッチを作っておき、指定されたオプションによって仮名か匿名かを決めていきたいと思います。

    .envに識別子のタイプを指定できるようにします。
    # 識別子の種別:PERSISTENT or TRANSIENT
    IDENTIFIER_TYPE=TRANSIENT

    次に識別子を生成するところのロジックを分岐させます。
    oauth2/oauth.js
    // 識別子タイプの判定(Persistent or Transient)
    let PPID;
    switch(process.env.IDENTIFIER_TYPE){
    case "TRANSIENT":
    // 魔界異なる識別子を生成する
    PPID = crypto.randomUUID();
    break;
    case "PERSISTENT":
    default:
    // Pairwise識別子の生成
    PPID = utils.createPPID(payload.local_identifier, req.query.redirect_uri);
    }

    以上で完成です。

    初回アクセスでの識別子(sub)の値

    2回目のアクセス時の識別子(sub)の値


    同じRPへのアクセスですがsubの値が変わっていることがわかります。

    今回のコードを含めこちらに挙げてありますので参考にしてみてください。


    2024年1月3日水曜日

    ログインさせたいユーザを指定してIdPへFederationする(SAML/OpenID Connect)

    こんにちは、富士榮です。

    SAMLでもOpenID ConnectでもFederation構成をしているとService Provider(SP)やRelying Party(RP)側であらかじめIdentity Provider(IdP)側で認証させたいユーザ名を指定したいケースがしばしばあります。
    典型的なケースの一つは多要素認証をオンデマンドで実行させた場合で、普通のページには第1要素であるユーザ名とパスワードで認証、決済ページには追加要素で認証を要求する、というシナリオは結構あり得るシナリオです。この場合、第1要素で認証されたユーザと追加要素で認証されたユーザをSP/RP側で比較することで同じ人であることを検証することももちろん可能なのですが、できればあらかじめ追加要素で認証させたいユーザの識別子をSP/RPからIdPに渡してあげることで利用者が再度ユーザIDをIdP側で入力する必要がなくなるのでUXも向上します。
    この様なシナリオは当然のことながらSAMLでもOpenID Connectでもサポートされています。

    SAMLの場合

    SAMLを使う場合、SPからのSAML Requestの中にSubjectを指定することができます。
    OASISのSAML2.0 coreの仕様の3.4.1のAuthnRequestのエレメントの章に記載があるSubjectが該当します。
    SAML 2.0 core仕様

    https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf

     こんな感じのリクエストになります。

    <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                        xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                        ForceAuthn="false"
                        ID="a133c62aafc8dcee7a69481de5af763c4ee370494"
                        IssueInstant="2024-01-03T03:28:40Z"
                        Destination="https://idp.example.jp/sso/login"
                        AssertionConsumerServiceURL="https://sp.example.com/acs"
                        ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                        Version="2.0"
                        >
        <saml:Issuer>https://sp.example.com/sp</saml:Issuer>
        <saml:Subject>
            <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">test@example.jp</saml:NameID>
        </saml:Subject>
    </samlp:AuthnRequest>
    実際の動作は上記リクエストを受け取ったIdP側の実装に依存するので利用するIdPの仕様を確認してださい。ちなみにEntra ID(Azure AD)の場合はこの方法ではなくクエリパラメータにlogin_hint=test@example.jpという形で付加してリクエストを投げる形になります。(この辺りを参照:https://learn.microsoft.com/ja-jp/entra/identity-platform/single-sign-on-saml-protocol#subject)ただし、Entra IDが外部IdPとFederationしている時はlogin_hintではなくusername=test@example.jpという形でパラメータ名が異なるので要注意です。
    また、Azure AD B2Cでは要求リゾルバという仕組みでSubjectの情報を取得することができるので、このサブジェクトに応じた処理を書けば割と自由に実装ができます。
    Okta CIC(旧Auth0)はSAML RequestのSubjectをちゃんと判別してくれそうです。(この辺りを参照:https://community.auth0.com/t/pass-login-hint-to-saml-provider/92546

    OpenID Connectの場合

    こちらはシンプルにlogin_hint属性をクエリパラメータに付加することで実現できます。(仕様はこちらを参照;https://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html)こんな感じでAuthentication Requestにパラメータをつけるだけです。
    HTTP/1.1 302 Found
      Location: https://server.example.com/authorize?
        response_type=code
        &scope=openid%20profile%20email
        &client_id=s6BhdRkqt3
        &state=af0ifjsldkj
        &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
        &login_hint=test@example.jp
    こちらもSAMLと同様にIdPの実装に依存するので実際の動作はIdPの仕様を確認してみてください。ちなみにAzure AD B2Cの場合はSAMLと同じく要求リゾルバで属性の取得ができます。

    ちなみに他にもヒント系のパラメータは色々とあります。
    また、SP/RPから認証コンテキストを指定したい場合もあるのですが、現在SAMLについてはAuthnContextClassRefというパラメータがありますが、OpenID Connectについてはacr/amrをclaimsパラメータで渡す方法はありますが、レベルの指定方法の共通化をどうするべきか?についてはPam Dingleさんを中心にIntenet Identity Workshopで議論が続けられているので今後の注目ポイントかもしれません。

    2020年5月2日土曜日

    Azure ADの外部コラボレーションとBYOID

    こんにちは、富士榮です。

    リモートワークで組織外の方々とのコラボレーションが大きなテーマになっている方々も多いと思いますが、そういう時はAzure ADの外部連携(B2B)の機能ですよね。

    そう言えばAzure ADのDirect FederationがGoogle以外にもSAML/ws-federationの外部IdPをサポートした、という会話をfacebookで某安納さんがしていたのを思い出したのと、先日 Alex Simons が色々と新しい機能が出たよ、というもはや個別の機能リリースの紹介だと無理だから一気にまとめて発表、みたいなポストをしていた中に、Azure AD B2CのSAMLサポートが正式リリースされた、という話があったので、もしやこれは繋がる???ということでやってみました。
    いわゆるBYOD(Bring Your Own Identity)ってやつです。

    当然、Azure ADのカスタムドメインを使った外部ID連携でも良いわけですが、この辺は後で比較をしてきます。


    まず関連する記事、ドキュメント類を。


    とりあえず完成イメージを

    言葉で説明しても伝わりにくいと思うので、どういうことが出来るようになるのか?を動画にしています。
    Azure AD B2Bで招待した外部ユーザでログインしようとすると、Azure AD B2Cにリダイレクトされ、LINEでログインすると、Azure ADにゲストユーザとして登録されてアプリケーションが使えるようになる、というシナリオです。


    Azure AD B2CのSAMLサポート

    先に書いた公式ドキュメント通りに設定していくと、Azure AD B2CがSAML IdPとして動作出来るようになります。(カスタムポリシーを使います。慣れると非常に簡単です)

    大きな流れは以下の通りです。

    Azure AD B2C側の設定
    • アサーション署名用の証明書(PFX)を作ってポリシーキーとしてアップロードする
    • ClaimsProviderとして、SAML2AssertionIssuerを作成する
      • MetadataにIssuerUriとして設定したものがIdPのEntityIDになります
      • CryptographicKeysに先にアップロードした証明書コンテナを指定するとアサーション署名をしてくれます(暗号化用証明書もアップロードすれば暗号化もできます)
    こんな感じの設定になります。
    <ClaimsProvider>
      <DisplayName>Token Issuer</DisplayName>
      <TechnicalProfiles>
    
        <!-- SAML Token Issuer technical profile -->
        <TechnicalProfile Id="Saml2AssertionIssuer_SAMPLE">
          <DisplayName>Token Issuer</DisplayName>
          <Protocol Name="SAML2"/>
          <OutputTokenFormat>SAML2</OutputTokenFormat>
          <Metadata>
            <Item Key="IssuerUri">https://nfpoc.b2clogin.com/nfpoc.onmicrosoft.com/B2C_1A_SI_SAML_SAMPLE</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="MetadataSigning" StorageReferenceId="B2C_1A_samlsampleapp"/>
            <Key Id="SamlAssertionSigning" StorageReferenceId="B2C_1A_samlsampleapp"/>
            <Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_samlsampleapp"/>
          </CryptographicKeys>
          <InputClaims/>
          <OutputClaims/>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-issuer"/>
        </TechnicalProfile>
    
        <!-- Session management technical profile for SAML based tokens -->
        <TechnicalProfile Id="SM-Saml-issuer">
          <DisplayName>Session Management Provider</DisplayName>
          <Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.SamlSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    


    • UserJourneyを定義する
      • この辺は通常のカスタムポリシーと同じです
    • RelyingPartyの定義を行う
      • 公式ドキュメントだとSAML SPに関するパラメータはAzure AD B2Cにアプリケーション定義を作ってマニフェストで設定する、ということになっていますが、Azure ADとB2Bとして連携する場合は、ちょっと工夫が必要です(後述します)

    Azure AD側の設定

    Azure ADの直接フェデレーションの設定を行います。
    • プロトコルはSAMLを選ぶ
    • IdPのドメイン名はSAML IdPの認証エンドポイントと同一ドメインである必要があるため、Azure AD B2Cのドメイン名(~.b2clogin.com)を指定する
    • 上記でAzure AD B2Cの設定が上手くいっていればSAML Metadataのダウンロードが出来るようになっていますので、保存したMetadataをアップロードして解析を行う
    直接フェデレーションの設定画面。ここで「新しいSAML/WS-Fed IdP」を選びます。

    こんな感じで設定します。



    設定としては非常にシンプルです。
    ただ、何点かクセがありますので、その部分を重点的に書いておきます。

    設定のポイント

    Azure AD B2Cのアプリケーション設定
    • ドキュメントを見ると、Azure AD B2Bと直接連携するためには以下の情報を設定する必要があることがわかります。
      • AssertionConsumerService
        • https://login.microsoftonline.com/login.srf
      • Audience(日本語ドキュメントだと「対象ユーザー」となっていますが。。。SAML SPのEntityIDのことです)
        • urn:federation:MicrosoftOnline
    • しかし、現状のAzure AD B2Cのアプリケーション登録ではカスタムスキームのAudience(urn:federation:MicrosoftOnline)をマニフェスト編集をしても登録することが出来ません。
    • ということで、SP(Azure AD)のMetadataを作って適当なところ(今回はbob)にアップロードし、カスタムポリシーから参照する形をとります。
    こんな感じです。
    <RelyingParty>
      <DefaultUserJourney ReferenceId="SI_SAML_SAMPLE" />
        <TechnicalProfile Id="PolicyProfile">
        <DisplayName>PolicyProfile</DisplayName>
        <Protocol Name="SAML2"/>
        <Metadata>
           <Item Key="PartnerEntity">https://nfpoccontent.blob.core.windows.net/root/aad_sp_meta.xml</Item>
    

    手動で作ったSP Metadataはこんな感じです。単純にEntityIDとエンドポイントさえ書いてあれば最低限はOKです。

    <?xml version="1.0"?>
    <md:EntityDescriptor
        xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
        xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
        entityID="urn:federation:MicrosoftOnline"
        validUntil="2031-12-31T00:00:00.000Z">
      <md:SPSSODescriptor
        protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://login.microsoftonline.com/login.srf"/>
        <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://login.microsoftonline.com/login.srf" index="0"/>
      </md:SPSSODescriptor>
    </md:EntityDescriptor>

    Azure AD B2CのSAML Metadata

    • 一応ドキュメントを漁ると出てくるのですが、見落としがちなので書いておきますが、以下のルールでMetadata URLが生成されます。
      • https://ドテナント名.b2clogin.com/テナント名.onmicrosoft.com/B2C_1A_ポリシー名/Samlp/metadata
    Azure AD B2CからAzure ADへ渡す属性(SAML AssertionのAttributeStatement)

    • ドキュメントを見るとnameidがpersistentであること、emailaddressを属性として渡すこと、とありますので、それに合わせてAzure AD B2CのRelyingParty設定を行います。具体的にはOutputClaimsの設定です。
    • また、標準的なAzure AD B2CのSAML設定だと結構冗長な感じでAttributeStatementが書かれるので、TechnicalProfileのMetadataにSaml11AttributeEncodingInfo(Saml20~でもOK)を指定することで少しすっきりします。
    こんな感じのRelyingParty定義になります。

    <RelyingParty>
      <DefaultUserJourney ReferenceId="SI_SAML_SAMPLE" />
      <TechnicalProfile Id="PolicyProfile">
        <DisplayName>PolicyProfile</DisplayName>
          <Protocol Name="SAML2"/>
          <Metadata>
            <Item Key="PartnerEntity">https://nfpoccontent.blob.core.windows.net/root/aad_sp_meta.xml</Item>
            <Item Key="Saml11AttributeEncodingInfo">
              <![CDATA[
                <saml:AttributeStatement xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
                <saml:Attribute AttributeName="emailaddress" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
                <saml:AttributeValue>
                </saml:AttributeValue>
                </saml:AttributeStatement>]]></Item>
          </Metadata>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId"/>
            <OutputClaim ClaimTypeReferenceId="b2cmail" PartnerClaimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" />
          </OutputClaims>
          <SubjectNamingInfo ClaimType="objectId" ExcludeAsClaim="true"/>
        </TechnicalProfile>
      </RelyingParty>
    </TrustFrameworkPolicy>

    ちなみにClaimType「b2cmail」は適当に適宜した属性なので自由に定義してもらえれば良いかと思います。重要なのは、「Azure AD B2Cのドメインと同じドメイン名を持つメールアドレスが設定されていること」です。例えば、hoge.b2clogin.comというAzure AD B2Cドメインを使っている場合は、fuga@hoge.b2clogin.comという値を返す必要があります。
    ※この辺りは早くAzure AD B2Cがカスタムドメインをサポートしてくれないと実利用するには辛いですね。

    いざ、動作確認

    設定はこれでおしまいです。
    しかし、あくまでこれはAzure AD B2Bにおける「外部ユーザの招待において独自のパスワードを払い出さずに済ませるための機能(これ重要)」なので、あらかじめユーザを招待しておく必要があります。

    ここは通常の招待と同じなので詳細は割愛しますが、Azure AD B2Cのドメインと同じドメインのユーザを指定して招待する、というところがポイントです。
    つまり、メールは届きません。(少なくともb2clogin.comを使っている限り、一般人はこのドメインでメールは届かないと思います)

    ただ、招待されている状態であれば招待元のアプリケーションにアクセスすれば招待の承認と同じことが起きますので、運用でカバーです。



    そして、これも公式ドキュメントに記載されていますが、現状B2Bの直接フェデレーションはマルチテナントアプリケーションでのホームレルムディスカバリが使えないので、招待元ディレクトリのテナントIDやドメイン名が明示的に指定されているアプリケーションしか動きません。
    例えば、

    • https://myapps.microsoft.comはダメ
    • https://myapps.microsoft.com/?tenantid=xxxxxxxxはOK
    という感じです。


    ここまで行けば、冒頭に動画で紹介した動きが再現できるはずです。
    ちなみに動画内では条件付きアクセスを使ってゲストユーザの初回ログイン時に利用規約に同意させる様にしています。

    カスタムドメイン単位でのフェデレーションと何が違うのか?

    ここで疑問が出てくるのが、元々Azure ADにはカスタムドメイン単位で外部のSAML/WS-FederationのIdPと連携する機能があります。ちょっと前に多くの企業がAD FSをオンプレにおいてOffice365とSSOをやっていた構成ですね。

    もちろんこのケースは社内ユーザを想定した話ですが、技術的に言うとB2Bの直接フェデレーションとほぼ変わりません。

    ただ、細かく見るとちょっとずつ違います。
    非常に雑な比較ですが、こんな感じです。

    カスタムドメインのID連携B2Bの直接フェデレーション
    フェデレーション単位ドメイン単位ドメイン単位
    ユーザの管理あらかじめ作成が必要(Azure AD Connectでの同期など)
    ImmutableIdでのマッチング
    あらかじめ招待が必要
    メールアドレスでのマッチング
    アプリケーションの制限マルチテナントでも可
    また、WS-Fedでwindowstranportエンドポイントの整備などの条件を満たせばWindows 10 PCログオンも可(Webサインイン設定不要)
    マルチテナントアプリは不可
    当然Windows 10 PCログインには使えない




    ということで、実用的かどうかはユースケース次第というところですが、日々色々な機能が拡張されてきているな、というところです。



    2019年6月28日金曜日

    Identiverse 2019参加メモ(Day3)

    こんにちは、富士榮です。

    いよいよ3日目です。そろそろ疲れてきました。
    これまでの日記はこちらから。



    ということで今日もはじめて行きます。
    まずはキーノートから。

    ◆キーノート

    • Digital Identity for the People by Richard Bird
      • Chief Customer Information Officerの人
      • 人々が自分のアイデンティティをデジタル社会に持つ時代になってきた
      • シートベルトなどと同じく、Consumer保護の考え方はデジタル社会が始まった当時は存在せず、後からポリシーがついてきた
      • GDPR、CCPAは果たしてConsumerの保護になっているのか?
        • 現実問題、施行後にも4億以上のアカウント漏洩が発生している
      • では何が足りないのか?
        • データ保護≠アイデンティティ保護
      • 結局のところ、アイデンティティの保護は人を守ること
        • いくらそのリンクをクリックしてはいけないと言ってもクリックする
        • 現実の数字として、
          • US国民の20%が家に鍵をかけない
          • 63%の強盗は押しいらなくても犯行ができてしまっている
      • デジタル社会で自分を守るということは?
        • データ保護とアイデンティティ保護は同一ではないことを認識する
        • MFAなどでアイデンティティを守ることが必要


    • Digital Identity - A Strategic Imperative by Grant Schneider
      • US FederalのCISOの人
      • 資料なしのプレゼンだったのであんまり拾えてないです
      • アイデンティティ管理はセキュリティのために非常に重要なものであると考えている
      • US連邦のサイバーセキュリティ戦略目標はデジタル社会におけるナショナルセキュリティと経済的なセキュリティを高めること、つまり「いかにして国家と国民の資産を保護するか」が命題
      • そのために、色々と守らなきゃダメ
        • Federal Cyber Security(税金や年金など)
        • 重大インフラのセキュリティ(金融システムや交通システムなど)
      • CEOやCIOがリスクマネージメントをできるように教育することも大事
      • もちろんプライバシーも大事なので、ペルソナの使い分けなども意識しないとだめ
      • アイデンティティ保証も大事だよ
    • The next wave of Identity Standard by Alex Simons
      • アイデンティティに関する標準の3つの波
        • オンプレミス
        • クラウドとモバイル
        • 分権とプライバシー by デザイン
      • オンプレミスにおける相互運用性と利便性の向上
        • 全てがFirewallの内側にある前提
        • ESSO、LDAPの組み合わせによるPasswordインジェクション
        • KerberosによるトークンベースのSSO
        • このころの攻撃はSlammerなどサーバの脆弱性を狙ったものが多かった
      • クラウドとモバイルの世界のためのアイデンティティ
        • SAML:広く使われるようになった最初の標準技術
        • OAuth1.0:実装が難しかったよね
        • OAuth2.0、OpenID Connect:現在のマイクロソフトのソフトウェアはPowerPointからAzureまでこの標準に従っている
          • 2019年6月のデータではAzure ADに接続されているアプリケーションの95%がOAuthもしくはOpenID Connectを使っている
        • このころになると攻撃手段が変わってきて、パスワード盗難がメインとなってきた
          • 81%のデータ漏洩の原因がパスワード盗難に起因している
        • こうなると多要素認証が必要となる
          • FIDO2。すでにWindows10やAndroidは準拠している
        • 次はパスワードレスの時代へ向かっている
          • Azure ADのパスワードレスのデモ(YubikeyでOffice365ポータルへログオンしてます)
          • 2019年7月にようやくAzure AD+FIDOのパブリックプレビューがリリースされる
          • 現状8億のユーザがパスワードレスを有効化している
          • 月間8500万ユーザがパスワードレスでログインしている
        • Token Binding
          • TLSだけじゃない
          • dPOPも
        • SCIM
          • 2019年6月のデータでは675万ユーザがSCIMでプロビジョニングされた
          • Mark Wahlが新しいSCIMのプロファイルを提案している
      • 分権とプライバシー by デザイン
        • 全ての人が自分のアイデンティティを自分でコントロールできる世界へ
        • DIDのデモ(昨日と同じもの) by Ankur Patel
        • まだまだこれから
      • とりあえず、今すぐやるべきこと
        • OpenID Connect、OAuthを使いましょう
        • モダンプロトコルに対応しましょう
        • パスワードレスの時代です
        • とにかく多要素認証を有効化しましょう。99%のID盗難は防げるよ

    • Standards: The Bedrock of Identity
      • パネルディスカッション
        • モデレーター:Pamela Dingle
        • パネリスト:Kim Cameron, Vittorio Bertocci, Brian Campbell, Annabel Backman
      • パネルはきつい。。。あんまり拾えてないです
      • それぞれがフォーカスしている/してきた標準仕様について紹介
      • そういえばVittorioはws-*の人だったなぁ
      • 標準化関連のミーティングはグローバルのあちこちで開催されるのは、みんなに参加してもらいたいから
      • しかしSAMLはなんで800ページにも及ぶ巨大なモノリスになってしまったのか
        • 何にでも対応できるように色々と組み込んでしまった
        • 結果、拡張が難しい巨大な仕様になってしまった
      • その反省を踏まえ、OAuth、OpenID Connectではシンプルなことをシンプルに実装できるように、という原則に則って設計をした
      • SecEventの話し。
        • SSOの世界ではリスクが顕在化した時にドミノ現象で伝搬してしまうので、リスクイベントの標準的な伝達方法が必要となった
      • プロトコル設計をする時はシンプルにすることが大事
        • DIDとOIDC、FIDOを組み合わせることで使いやすい姿を模索するなど
      • これからこの世界をドライブしていこうとしている人たちへメッセージは?
        • 標準化の世界へぜひ参加して
        • コミュニティへ参加すること。メーリングリストがあるので、そこでユースケースや考えたことを共有するところから。Don't be shy!
        • 言語の壁もあるかも知れないけど気にするな

    ◆ブレークアウトセッション

    • The Identity Architecture Panel
      • パネルディスカッション
        • モデレーター:Barber Amin
        • パネリスト:Kristina Williams, Greg Smith, Stephanie Kesler, Kim Cameron
      • やっぱりパネルはきつい・・・
      • ゼロ・トラストの世界。ブロックからモニター、緩和へ
      • 企業は従業員にとってのIdentity Providerが、管理者はSAMLを知っているわけではないし、我々(IDaaS事業者)はインフラの形を変え管理者が何もしなくても良い世界を作ろうとしている
      • プライバシーはコンシューマだけでなく従業員にとっても非常に重要
        • CIAMのアプローチでは管理者はアイデンティティを管理することができない
        • エンタープライズIAMの世界では管理者が従業員のアイデンティティを管理する
        • コンテキストに合わせた柔軟なユーザージャーニーが必要である
        • マイクロソフトは固定的なログインを柔軟にするためにIdentity Experience Framework(IEF)を提供している
        • IEFを使えば、コンテキストに合わせた柔軟なユーザージャーニーを提供することが可能である
        • 例えば、HRシステムの重要なデータへアクセスする際は追加の認証を要求する、なども考えなければならない
      • どのようにして開発者にプライバシーを保護を意識させるのか?
        • 教育なども重要
        • データの分類と評価がまずは大事
      • 昨年、テレコム企業の課金システムのリプレイスを行なった
        • アーキテクチャの全面書き換えを行った
        • 保護されたAPIやデータへのアクセスをトークンを使って制御することにした
      • CCPAがあるけど、何かアドバイスは?
        • まずはデータを特定して分類するところから始めましょう
      • DIDについて
        • iPhone上のデータは誰の持ち物?Appleもデータのコントロールできちゃうよね
        • 個人データは借財。これは長くは続かない。DIDとかブロックチェーンが解決の糸口になるかもしれない
        • 5年から10年くらいはかかるかな
      • 今後我々はどんなテクノロジーをキャッチアップしていけばいい?
        • AI(プライバシーも考慮して)
        • FIDO2
        • コンテキストに合わせたユーザージャーニー(IEF)
        • マシンラーニング
        • Decentralized Identity

    • Blurring the boundaries between CIAM and IAM / Microsoft
      • アイデンティティはセキュリティの要である
      • 社内外とのコラボレーションのあり方の変化
        • B2Bシナリオ
          • パートナー側でアイデンティティを管理する
          • つまりBYOID
        • B2Cシナリオ
          • セルフサインアップ
          • 同じくBYOID
      • こうやってみるとB2BもB2Cも同じ
        • アカウントを作って
        • 承認して
        • アクセスできるようになる
      • 共通しているのは人を中心に据えていること
      • サンプルケース1
        • 個人が複数のロールを担うことがある(不動産のオーナーだったり、売主だったり、従業員だったり)
        • 一つのGoogleアカウントでサインアップ〜サインインする(Azure AD B2B)
        • システム側でロールを切り替えられるような実装をすることで、役割ごとにユーザアカウントを個別に作る必要がなくなる
      • サンプルケース2
        • 大学のケース
        • 入学希望して、受験生となって、学生になって、卒業生になって、大学院に入ってまた学生になって、学校に就職して職員となって。。というライフサイクル単位でアカウントを作るのではなく、一つのアカウントの状態を変えていく
      • 共通するのは、一つのアカウントを関係性に応じて変化させていく、という考え方

    • Identity Proofing - What Happens Before Authentication by Capital One
      • Identity Proofingとは
        • 個人に関する情報を集めて検証するプロセス
        • アカウントをオープンする時に実行したりする
        • 認証とは異なる
      • なぜIdentity Proofingが重要なのか
        • 認証して認可してシステムやデータへアクセスさせるが、そもそも「誰?」という部分を知らなければならないため
      • NIST SP800-63Aにおける定義
        • Resolution
        • Validation
        • Verification
      • Identity Assurance Levelとは
        • 検証に使うエビデンスと方法の品質
      • 企業におけるシナリオ
        • 雇用時
          • バックグラウンドチェック
          • 対面での書類確認
          • 初期クレデンシャルの発行
        • クレデンシャルのリカバリ時
          • パスワードレスのシナリオの場合
          • 免許証などのドキュメントをビデオ会議で見せて確認する
      • コンシューマの世界におけるIdentity Proofing
        • スピードと正確性とコストが大切
        • 時間がかかると顧客はドロップしてしまう
      • 色々な方法
        • モバイルデバイスを使った確認
          • SMSへのコード送信
        • ドキュメントを使った確認
          • 券面のスキャン、バーコードのスキャン
          • 券面のスキャンはPhotoShop対策も合わせて必要
      • リスクベースアプローチが必要
        • Identity ProofingはRiskスコアと同義でもある
      • まとめ
        • 一般的にユーザが提供したり手動で入力した個人データは不正確である
        • システム横断で使えるRiskスコアが必要
        • データソースを増やして、検証の精度を高めるためには外部ベンダーとの協業が必要である(Capital Oneとか)

    • Frictionless Identity Verification by ADP
      • ADP自体はセキュリティの会社ではなく、HCMの会社
      • 40Mくらいのアクティブユーザー数がある
      • 次のチャレンジはユーザエクスペリエンスの改善
      • 現状、ADPのサービスに従業員がセルフ登録する方法は以下の通り
        • Federated SSO
        • Personal Code
        • Company Code
        • Codeless Registration(モバイル向け)
      • これまでIdentity Assuranceを担保するためにやってきたこと
        • Bot Protection(ロボットよけ)
        • AIベースのアイデンティティ確認
        • 知識ベースの認証
        • デバイスベースのリスク管理
        • 外部ベンダとの協業(Capital One)
      • 登録時のユーザージャーニーを整理し、70%のコンバージョンを実現した

    • So You Think You Can Two Factor by Nishant
      • 多要素認証を使う時
        • PSD2など法令により必須な時
      • 認証要素は非常に多岐にわたっている
      • これらを単純に提供するのは説明書なしで家具を組み立てさせるようなもの
      • どのように利用させる要素を考えるか
        • ユーザが使いやすいもの
        • コスト
        • 対応する脅威モデル
        • 効果
        • 法令遵守
      • 生体認証はセキュリティではなく、利便性のためにある
      • 生体情報(いわゆる身体的な特徴情報)はすでに必須ではない
      • ユーザの行動、デバイスID(Fingerpirnt)を使ったアノマリ検知も可能(機械学習ベース)
      • ユーザへの浸透(使い慣れているものを使う)
        • Googleは7年前から2要素認証を提供しているが利用している人は10%程度だった
        • Yubikeyに対応したら登録者が増えた、なぜならYubikeyを使っている人が増えたから
        • ユーザはリスクを理解しているわけではない
        • Googleは2要素認証を強制はしていない。なぜならサービスを使わせたいから
      • オムニチャネルの検討
        • UX向上の別の例
        • コンタクトセンターでの認証をスマホで行う、などチャネルを分離することによるUX向上とセキュリティ向上の両方を実現
      • プロセス自体の検討
        • 付与
          • 第1要素を付与する時に同時に2要素目の登録を行う
          • 間が空くと弱いタイミングができてしまう
        • バックアップを取得する
        • 緊急避難のパスを作っておく
        • リカバリプロセスを作っておく(例えばSMSや免許証での検証など)
        • 第2要素の破棄の方法を考えておく
      • まとめると以下が大事
        • ちゃんと使えること
        • 複数の方法を用意しておくこと
        • ユーザが受け入れられること
        • オムニチャネルの検討
        • 管理プロセスの検討

    • Why Governments are still important even in a Self-Sovereign Context by Adam Cooper
      • 近い将来、デジタルアイデンティティが人々のプライマリのIDになったと仮定するとどうなるだろうか
      • 政府機関の役割
        • 法律を整備する
        • アイデンティティドキュメントを交付する
        • 住民登録データを記録・保管する
      • SSIやDIDのような新しい仕組みはそれらの役割を代替するものではなく、相互運用するものである
      • 実際にアイデンティティを使う際にはアイデンティティそのものよりも適格であるかどうかの方がはるかに大切である
        • 例えば、支払い能力はあるか、など
      • そうなると、政府機関の提供するアイデンティティはトラストの源泉としての役割を持つ
      • 個人は自身のアイデンティティを提示する際に、信頼できて検証可能であることを望む
      • つまり、ポータブルで信頼に裏打ちされた状態において、自身でアイデンティティの管理を行える状態が望ましい
      • 結局トラストフレームワークが鍵となる

    • Developing World Identity
      • パネルディスカッション
        • モデレーター:Jeremy Grant
        • パネリスト:Adam Cooper, Vyjayanti Desal, Kaliya Young
      • ID4Dの取り組みの紹介(World Bank)
        • LIC(Low Income Countries)にフォーカスしている
          • ペルー、インド、パキスタン、タイなどで活動
        • デジタルIDは全ての基盤となる
          • Financial Inclusion
          • Healthcare
          • Women's Empowerment
          • Social Protection
          • Education
        • 他にもペーパーレス・トランザクション(Paymentなど)を行う上でも必要なものである
        • ID4Dの3つのアプローチ
          • Thought Leadership & Analytics
          • Country & Regional Action
          • Global Platform & Convening
        • 啓発活動を含め各種ドキュメントの発行なども行なったり、原則をプラクティスへ落とし込む活動をしている
        • グローバルで一つの大きなIDシステムを作ろうとしているわけではなく、各国がオープンなIDシステムをもち、相互運用性を持てるような世界を目指していく
      • Aadhaarの話(Kaliya)
        • 2000年代初頭、IDシステムをどうやって変えていくか考えた
        • 国民を登録する台帳は存在、ローカルガバメントが誕生・死亡の登録を管理していた
        • Nandan Nilekani氏が閣僚となり、インドのユニークIDのオーソリティを作ることとなった
        • 最低限実行可能なID基盤として以下をもつ
          • 名前、生年月日、性別、住所
          • 生体情報(写真、2つの虹彩情報、10の指紋情報)
          • (ボーナス。必要か?)電話番号、メールアドレス、銀行口座情報
        • 登録時はセントラルレポジトリへデータが送られ、ユニーク性のチェック後、IDが発行され、カードが送付される(なんのセキュリティ機能もないカード)
        • Aadhaarを使った認証の方式
          • Aadhaar番号と名前、住所
          • Aadhaar番号と生体情報
          • Aadhaar番号とワンタイムパスワード
          • Aadhaar番号と多要素認証
          • (KYC時は)Aadhaar番号と生体情報+eKYCドキュメントの名前と住所
        • 問題点
          • 住民のゴールデンレコードができてしまう
          • セキュリティ保護されていないカードが存在する
          • 地方の支局に行くと生体情報の確認ができないことがある
          • ワンタイムパスワードを使おうとしても携帯電話番号を持っていない人がいる
        • 良い点
          • みんなが持っている
          • ユニバーサルである



    と、本編はここまでです。
    この後、イベントのFounderであるPing IdentityのCEO、Andre主催のパーティに参加してきました。Newseumという報道関係の博物館を貸し切っての大イベントでした。
    ちなみにベルリンの壁とかがありました。
    しかし何と言っても目玉はID厨だけで構成されているバンド、ZZAuthです。
    メンバが以上に豪華です。Eve Malar, Justin Ritcher, Alex Weinert, Pamela Dingle, Sofia-Cristineなどなど・・・





    ということでいよいよ次回は最終日です。

    2019年3月26日火曜日

    [Azure AD B2C] Custom Policyが遂にGA!

    こんにちは、富士榮です。

    Public Preview開始から約2年、ようやくAzure AD B2CのCustom Policy(Identity Experience Framework)がGAしました。


    公式アナウンス
     Azure AD B2C custom policies to build-your-own identity journeys reaches general availability
     https://techcommunity.microsoft.com/t5/Azure-Active-Directory-Identity/Azure-AD-B2C-custom-policies-to-build-your-own-identity-journeys/ba-p/382791

    といっても何のことか、という方もいらっしゃると思いますので、簡単に。

    Azure AD B2Cには
    ・ビルトインポリシー
    ・カスタムポリシー
    の2種類があります。

    ざっくりいうと、ビルトインポリシーで出来るのは、
    ・プリセットされた外部IDプロバイダ(FacebookとかTwitterとか)の利用
    ・サインアップ、サインイン、プロファイル変更、パスワードリセットというアクション
    ・OpenID Connectを使ったアプリケーションへのID連携
    です。

    まぁこれでも十分と言えば十分なのですが、カスタムポリシーを使うことで、
    ・プリセット以外の外部IDプロバイダの組込み(LINEとかYahoo! JAPANとか、SAML IdPとか)
    ・複雑なアクション(複数のIDプロバイダのIDの紐づけとか、外部のREST APIの呼び出しとか)
    ・SAMLなどOpenID Connect以外のアプリへのID連携
    など、割りとなんでもできてしまいます。

    もちろん、今回のGAでカスタムポリシーのすべての機能がGAしている訳ではありませんが、Azure AD B2Cを使って出来ることが大幅に広がりました。

    ※現状のリリース状況(Preview/GA)はこちらから確認できます。
    https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-developer-notes-custom

    まだまだドキュメント等、充実しているとは言えませんが、今後に期待です!



    2018年12月21日金曜日

    TechSummitのおさらい③:Azure AD + Auth0 で条件付きアクセスを構成する

    こんにちは、富士榮です。

    そろそろディープになってきました。公式イベントで話すにはかなり気が引けるネタ度Maxです。

    今回はAuth0(おーすぜろ)とAzure ADを組み合わせることで複雑なことをやろう!という話です。

    もちろんAzure ADにはPremium P1/P2という複雑なことをやりたい人向けのプレミアなライセンスがありますので、お金に余裕のある方、一気通貫でサポートを頼みたい方は迷わずそちらを選んでください。

    Auth0とは?

    Auth0もMicrosoftやOkta、PingIdentity、OneLoginなどと同様にIDaaS(Identity as a Service)を提供しているサービスプロバイダです。jwt.io辺りで有名ですね。
    ちなみにFounderは元マイクロソフトのEugenio Paceです。「A Guide to Claims-Based Identity and Access Control」をVittorio Bertocciと一緒に書いた人ですね。まだ彼がMSにいる時代にやり取りをしてサイン本をもらったりしたもんです(遠い目)。最近は共著のVittorioもAuth0へ移ったのが個人的なビッグニュースでした。

    少し特徴的なのは「開発者向け」である、という売り出し方をしているところですね。開発者向けたる所以は、ひたすらかゆいところに手が届くから、というのが最大の理由だと思います。

    このAuth0、実は別のサービスとしてWebtaskというFaaS(Function as a Service)を提供しており、ID関連の機能の各所にこのWebtaskをどんどん差し込んでいくことが出来るんです。このことにより、例えばid_tokenの中身を見て処理を実行したり、ID登録直後に別の処理を走らせたり、など開発者がやりたい放題出来てしまいます。


    Azure AD + Auth0?

    さて、Azure ADとAuth0を組み合わせると何が出来るのか?という話に移りたいと思います。
    Auth0はAuth0自体にIDを保持して自身がIdPとして振舞う以外に、外部のIdP(Connectionと呼んでいます)とID連携する機能を持っています。また、当然のごとく外部のSPとID連携することもできます。
    このことを使い、IDの保持とベーシックな認証機能はAzure ADで、複雑な処理(今回は条件付きアクセスと多要素認証)はAuth0で担当、というようなことを実現することが出来ます。
    使えるプロトコルも多様なので、アプリ(今回はG Suite)とAuth0の間はSAML、Auth0とAzure ADの間はOpenID Connect、という構成を組んでみました。


    Azure ADのアプリ(RP)としてAuth0を登録

    早速構成していくわけですが、まずはAuth0の外部IdPとしてAzure ADを構成するためには、Azure ADのRelying Party(RP)としてAuth0を登録してあげる必要があります。具体的には、ReplyUrl(応答URL)にAuth0のエンドポイント(Callback)を登録し、Auth0側に設定するためのClient IDとClient SecretをAzure ADから払い出します。

    Azure ADのアプリ登録メニューより登録を行います。
     Azure ADに登録するAuth0のCallback URLは以下の通りです。
      https://{テナント名}.auth0.com/login/callback


    Auth0の外部IdPとしてAuth0を登録

    次は、逆側の設定なので、Auth0にAzure ADの情報を登録していきます。
    ちなみにAuth0はビルトインのConnectorとしてAzure ADが用意されているので、こちらを使ってもいいですし、OAuthを使ってカスタム接続するためのExtensionもあるのでこちらを使って接続しても問題はありません。

    こちらがビルトインのAzure ADとの接続Connector

    こちらがOAuthを使うExtension


    私は後者のExtensionを使っています。(というかビルトインでAzure ADが存在しているのを知らなかった・・・)
    Azure ADの認可エンドポイント、トークンエンドポイントと先ほどアプリ登録した際に取得したClient IDとClient Secretを登録します。

    ちなみに、例のWebtaskを使ってGraph APIでAzure AD上のユーザ情報を取得することが出来ます。SAML Assertionに属性を入れてアプリに渡す必要があるので、必要な属性を取得する様にスクリプトを作ります。
    function(accessToken, ctx, cb) {
    
      request.get('https://graph.microsoft.com/v1.0/me', {
          headers: {
            'Authorization': 'Bearer ' + accessToken,
          },
          json: true
        },
    
        function(e, r, u) {
          if (e) return cb(e);
          if (r.statusCode !== 200) return cb(new Error('StatusCode: ' + r.statusCode));
          var profile = {
            user_id: u.userPrincipalName,
            name: u.displayName,
            email: u.mail
          };
          cb(null, profile);
        });
    }
    


    直観的にわかりやすいスクリプトだと思うので、あまり解説する必要もないとは思いますが、トークンエンドポイントから取得したアクセストークンがコンテキストとコールバック先のオブジェクトと一緒に渡ってくるので、Graph APIにアクセスして必要な情報を取得、Profileとして設定して返却してあげる、という流れです。

    G SuiteとAuth0をID連携

    ここはこれまで何度となく解説してきたG Suiteのシングルサインオン設定の世界なので、G Suite側は目をつぶっていても構成できてしまう世界だと思いますので、Auth0側の設定を中心に。

    ちなみにAuth0にはApplicationギャラリー的なプリセット・アプリのリストは存在しません。めちゃくちゃシンプルにNative App、SPA、Regular Web App、Machine to Machine Appの4種類しかありません。

    G Suiteなど通常のアプリを使う場合はRegular Web Appを選びましょう。

    また、Regular Web Appを選んだとしてもデフォルトではアプリと言っても単純なOAuthのクライアント登録しか出来ないので、AddOnという形でSAML等のプロトコルを設定してあげる必要があります。
    SAMLの設定もかなりプログラマブルなので、Assertion内の各種パラメータをガリガリと書いていきます。本当に痒い所に手が届きます。ほぼ出来ないことは何もないので、Assertionの書き方の方言でうまくアプリと繋がらない、というトラブルとは無縁だと思います。その代わりSAML Assertionの中身の仕様について熟知している必要はありますが。


    この構成のページからIdP MetadataやAssertion署名用の証明書のダウンロードなども可能なので、エンドポイントや証明書をG Suite側に設定してあげれば完了です。

    これで一通り単純なシングルサインオンについて出来るようになっています。


    条件付きアクセスを構成する

    ここまでだとAuth0がG SuiteとAzure ADの間に挟まっている必要性が全くないので、最初に書いた通り、条件付きアクセスを構成してみます。
    本来Azure ADではPremium P1のライセンスが必要な機能です。

    Auth0での条件付きアクセスを構成するには、Rulesメニューよりルールを構成します。
    このルールもJavascriptでガリガリと書いていくことが出来るので、ものすごく柔軟です。アクセス元の状態はContextから取得できるので、ソースIPやUser Agentなど様々な情報を見て多要素認証の適用の有無など各種条件を設定することが可能です。
    function (user, context, callback) {
      const ipaddr = require('ipaddr.js');
      // 社内ネットワーク
      const corp_network = "x.x.x.x/16";
      // 対象のアプリケーションのclient_id
      const CLIENTS_WITH_MFA = ['G SuiteのClient Id'];
    
      // 接続元のソースIP
      const current_ip = ipaddr.parse(context.request.ip);
      if ((!current_ip.match(ipaddr.parseCIDR(corp_network)) && (CLIENTS_WITH_MFA.indexOf(context.clientID) !== -1))) {
          context.multifactor = {
            provider: 'google-authenticator',
            allowRememberBrowser: false
          };
      }
    
      callback(null, user, context);
    }
    


    ここまで構成すると社内アドレス以外からG Suiteを使おうとすると多要素認証(今回はGoogle Authenticator)を要求される様になります。



    こんな感じでAzure AD+Auth0で見た目はぼぼAzure AD Premiumの条件付きアクセス、ということが実現できてしまいました(笑)。

    まだまだネタは続きます。では次回!

    2018年12月19日水曜日

    TechSummitのおさらい②:Azure ADとSaaSアプリのSSO構成時のトラブルシュートあれこれ

    こんにちは、富士榮です。

    前回に引き続きTechSummitのフォローアップです。

    今回は2つ目のネタ「SaaSアプリのSSO構成時のトラブルシュートあれこれ」についてです。

    簡単に言うと、同じ種類のSaaSアプリを複数インスタンス(例えば本番環境と開発環境とか)を単一のAzure ADとSSOの構成をしようとすると動きがおかしくなる「ことが」ある、というお話しです。

    よくあるシーンはこんな感じで、本番・開発の2環境を用意したいけど、Azure ADってテナント毎、ユーザ毎のライセンスなので出来ればAzure ADは単一の環境で済ませたいよね、っていう話です。

    TechSummitでは個人的な経験を基に、G Suiteを複数インスタンス用意してSSOを構成しようとしたとき、たまに発生する問題を紹介しました。
    ※ちなみにSalesforceでも起きることがあるようですが、すべてのアプリで発生するわけではありません。また、G Suiteでも毎回起きるわけではありません。

    何が起きる(た)のか

    先ほど書いたように、毎回起きるわけでもなく、発生条件も良くわからない状態なので、ここに書いたことが必ず起きるわけでもなく、他に発生する問題がある可能性もありますが、とりあえず私が体験したことを書いていきます。

    • NameIDの値のマッピングが上手くいかない(UPNを使ってくれない)
    • SP EntityIDが一致していない、と言われる


    NameIDのマッピング不良と対策

    まずは前者です。
    初期状態のAzure ADはG SuiteのSSO構成時、NameID属性としてuserPrincipalName属性をマッピングします。また、G SuiteのNameID Formatの指定はunspecifiedです。

    通常、この構成だとAzure ADはuserPrincipalNameの値をそのままG Suiteへ渡すのですが、なぜか仮名が生成されてNameIDとして渡されてしまうことがあります。通常はNameID FormatがTransientやPersistent以外は仮名が生成されることは無いはずなのですが、何かがおかしいです。


    これを解消しようとすると、Azure AD側のでNameID Formatを明示的に指定してあげる(つまり、G Suiteからの指定を無視する)必要があります。
    G Suiteはメールアドレス形式でNameIDの値が飛んでくるのを期待しているので、NameID Formatをemailaddress(電子メールアドレス)にしてあげます。


    これでうまくいきます。


    SP EntityIDの不一致

    次に、SSOを試みた時に出てくる「AADSTS65005: Misconfigured application」エラーへの対策です。このエラーはAzure AD側でアプリケーション構成がおかしいので見直せ!というエラーです。


    最近はAzure ADのSSO構成も人にやさしくなっており、エラーの詳しい原因が管理ポータルからある程度確認できるようになっています。(Salesforceが昔から実装していた機能ですね)
    これまでSAMLのやり取りをトレース&解析しないとダメだったのですが、この機能が出来てかなり楽になりました。

    この機能を使って先のエラーの原因を探ると、なぜかSP EntityID(要するにアプリケーションを一意に識別する情報)がマッチしていない、と言われます。どう見ても一致してるんですが・・・
    もちろんアプリケーションが一つしか構成されていない状態ではこのようなことは言われないのですが、G Suiteを複数インスタンス構成するとタマにこのエラーが出ます。
    ※ちなみに昔はもっとひどかった(構成するとユーザの割り当てが混ざったりしていた)ので、マシにはなったんですが・・・


    実はこのエラーが出ると、Azure AD側ではどうしようもなく、強引に複数のG Suiteインスタンス間でEntityIDが絶対に重複しない様に構成を工夫するしかなくなります。
    今回やったのは、片方のG Suiteについて、Google側でEntityIDにドメイン固有情報を含めるのを辞める、という苦肉の策です。
    これで複数のG Suiteインスタンス間で必ず異なるEntityIDが使われるようになるので、問題が解決します。(本来はこんなことをしなくても必ず異なるEntityIDは使われるんですが)



    まぁ、今回紹介したものは発生することもある、というレベルなので仕組みを理解した上で適度に使ってもらえれば、というレベルの話でした。

    引き続きフォローアップをしていきますので、お楽しみに。


    2018年12月17日月曜日

    TechSummitのおさらい①:Azure ADで非SSLアプリとのSSOを構成する

    こんにちは、富士榮です。

    ようやく秋口からのセミナーラッシュが落ち着いてきたので、先日のTechSummitでお話しした非公開ネタを解説していきたいと思います。

    内容的にマイクロソフトの公式イベントでお話しするにはあまりにも非サポートだったり、別の会社の製品との組み合わせを紹介しすぎたり、と大人の事情満載だったので当日は撮影禁止&資料・動画公開なしとさせていただいたネタです。

    当日お話しした内容は公開可のモノも含めると以下の通りです。


    1. 非SSLな開発環境とSSOを構成したい!
    2. SaaSアプリとのSSO時のトラブルシュートあれこれ
    3. Azure AD Premiumは買えないけど複雑なことをやりたい
    4. SaaSアプリへのプロビジョニングがちょっとアレな話
    5. マルチフォレストのオンプレADとの同期すときのあれこれ
    6. マルチフォレスト構成時のパスワード同期元/先を制御したい!

    と、言うことで順番に解説していきたいと思います。
    今回は1番目の「非SSLな開発環境とSSOを構成したい!」です。

    Azure ADがSSOを構成するアプリはSSLじゃないとダメ!?

    すでにAzure ADをお使いの方はご存知だと思いますが、Azure ADを使ったアプリとのSSOを構成するには、アプリをSSL化しておくことが前提となります。
    この時に困るのが、開発環境をどうするか?という話です。もちろん余裕のある方は開発環境を含めてSSL化しておくことも可能でしょうし、最近はLet's Encryptなど無償の証明書を発行してくれる機関もあるので、こちらを活用して行くことも可能なのでニーズは減ってきていると思いますが、やはり面倒ということもあり何とか手軽に非SSLな開発環境でもSSOを構成していきたいところです。
    ※もちろん非SSLな環境を推奨している訳ではありませんので誤解なきよう。。。

    非SSLなアプリを構成しようとすると何が起きるか?

    先ほど、標準のAzure ADだとアプリのSSL化が前提となっている、という話をしましたが、具体的に何が起きるのか?を先に説明しておきます。
    といっても単純にSAMLアプリの場合はAssertion Consumer Service(ACS)、OpenID Connectアプリの場合はReply URIを設定する際にhttpsスキーム以外だと怒られて設定が出来ない、というだけです。


    ここで、考えるべきなのは
    • このエラーはUI上でのValidationの問題なのか?
    • それともデータを保存する際のValidationの問題なのか?
    ということです。

    個人的な経験からすると、Azure ADの構成情報の実体データは割りと素な状態でストアされており、管理者はPowerShellやAPI(そしてオマケとして管理ポータル)で設定を行うという構造になっていますので、今回についてもACS/ReplyURIの元データを何とかして修正できれば目標を達成できるはず、と考えました。

    Azure ADにおけるアプリ登録情報の実体

    ということで、管理ポータルの存在は一旦忘れて登録されたアプリケーションの構造を生データで見ていきましょう。
    まずは一番単純な方法としてPowerShellを使います。※ここは時間の関係でTechSummitでもお話ししなかった部分です。

    Azure Active Directory Module for Windows PowerShellを使いますので、インストールしていない人は「Install-Module -Name AzureAD」あたりで先にモジュールをインストールしておいてください。

    取り敢えず「Connect-AzureAD」でAzure Active Directoryへ接続しましょう。
    次に登録済みアプリケーションの情報を確認するために「Get-AzureADApplication」を実行します。

    登録されているアプリがずらりと出てきます。


    この中から、構成をしたいアプリケーションを見つけて、ObjectIDを指定して再度「Get-AzureADApplication」を実行して構成情報を確認します。この時、パイプでflをつけると細かいパラメータが見えます。
    こんな感じです。
    「Get-AzureADApplication -ObjectId xxxxx | fl」

    その中にReplyUrlsというパラメータが見えます。

    SAMLだろうがws-federationだろうがOAuthだろうがOpenID ConnectだろうがReplyUrlsです。潔すぎです。
    この値がSAMLの場合はACSのURL、ws-federationの場合はwreply、OAuth/OpenID Connectの場合はReplyURIですね。

    PowerShellを使って値を変えてみる

    アプリの構成を取得するときに使ったのが「Get-AzureADApplication」なら構成を変更するときに使うのは「Set-AzureADApplication」です。

    ただ、このReplyUrlsは配列で値が入るので、セットしたい値は配列としてセットします。PowerShellの場合は「@("値1","値2")」という形式が必要です。

    ということで、
    「Set-AzureADApplication -ObjectId {アプリのGUID} -ReplyUrls @("http://{ACSのURL}")」
    をしてあげます。

    以上、終了です。

    先ほどと同様にGet-AzureADApplicationで確認するとちゃんとhttpスキームでReplyUrlsが登録されていることがわかります。もちろんデフォルトのhttpsを残したままhttpのモノを追加してもOKです。単純に配列に値を追加すれば良いだけですので。

    結果、非SSLなアプリケーションへもSSO出来るようになりました。


    管理ポータルでも構成が出来る

    どうしてもPowerShellに抵抗がある人は手を挙げてください。
    はい、実は管理ポータルでも構成変更が出来ます。
    (こちらがTechSummit当日にご紹介した内容です)

    やり方は登録されているアプリのマニフェストを直接編集します。
    変更する内容はPowerShellの場合と同じく、ReplyUrlsの値です。





    スライドにも書いてありますが、ここを変えても元々のエンタープライズアプリケーションのSSOの設定の表示が変わるわけではありません。


    取り敢えず今回は一つ目の話を解説しました。
    2つ目以降についても順次紹介していきたいと思いますので、しばしお待ちください。