2021年5月27日木曜日

Build 2021で発表されたAzure AD B2Cのアップデート

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


今年も Build のシーズンですね。

Ignite に比べて主に Developer 向けの Update がメインなカンファレンスなので Identity 要素は薄めですが、もろもろ発表はありました。

※主にこのセッションからです。


ざっくりですが、すでに発表済みだったものも入れるとこんな感じです。

(ドキュメントが公開されているものはリンクしておきます)



Apple ID サポートは2年くらい前にカスタムポリシーで実装してたやつですね。その後 Private Preview で一部では提供されていたので私も評価していたんですが、しばらく前に全面的にリニューアルされて出てきました。ただ、個人的には iOS も最近は Platform Authenticator としてつかえるので Apple ID としてサポートするよりも FIDO として実装しちゃった方がいいじゃないかな?と思ってます。(仕事で Azure AD B2C のデプロイする場合は FIDO でやっちゃってます)

昔実装した様子の動画



Verifiable Credentials を使ったログインは個人的にも注目している領域です。デモはされていましたが、正式に Claims Provider として Verifiable Credentials がサポートされるのかどうかはわかりません。




実は私も半年くらい前にこの辺りの実装をしてみてました。こんな感じの動きになります。



Identity Protection 連携はこちらも以前投稿したやつですね。ようやくGAです。



API Connector はカスタムポリシーを使いたくない人向けですね。(私はユーザーフローは基本使わない人なのであんまり興味ないです)



カスタムドメインもちょうど先日投稿したやつですね。Azure Front Door を使って実装するやつです。これまで Microsoft と交渉しないと使えなかった機能なので、今更ながらに非常に嬉しい機能です。



他にも Ask the Expert セッションを聴いていると色々とポロリもあったりして面白かったです。(TOTP の Private Preview の話とか)


最近は Identity Verification Partner との連携などエコシステムも育ってきつつある Azure AD B2C ですが、Microsoft 自身によるエンハンスも着実に進んでいるみたいなので引き続き楽しんで触っていけそうです。



2021年4月19日月曜日

[Azure AD B2C]カスタムポリシー内のエラーハンドリング

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

たまには小ネタを。


Azure AD B2Cのカスタムポリシーを使ってUserJourneyを構成する際に悩ましいことの一つはエラーハンドリングです。

初期状態だと、UserJourney内のOrchestrationStepでエラーが発生した場合はエラーメッセージをパラメータにつけて呼び出し元のアプリケーションへリダイレクトする、という振る舞いをするので、アプリケーション側で発生しうるエラー毎に振る舞いを定義してあげる必要があります。


かっちりした開発をする場合はちゃんとアプリケーション側でエラーハンドリングをするのが正解だとは思いますが、アプリ側に手が入れにくい場合などある程度Azure AD B2C側でエラー画面を出して処理を止めたい場合もあります。こういう時に使うのがUserJourneyBehaviorsに定義するOnError Modeです。
とりうるパラメータと振る舞いは以下の通りです。
  • DisplayInService:Azure AD B2Cのフローの中でエラーメッセージを表示して処理を止める
  • ReturnToRequestor(Default):呼び出し元アプリケーションへエラーメッセージをつけて戻す

試しに絶対にエラーになるREST APIを呼び出すClaimsProviderを作りUserJourneyの中で呼び出して見ます。

ServiceUrlがhttps://www.example.com/apiとなっているのでNot Foundとなり、このTechnical Profileは絶対に失敗します。

このUserJourneyを呼び出すRelyingPartyのOnError ModeをDisplayInServiceにセットして見ます。


これでフローを実行してみると一番最初に貼り付けた画像の挙動(初期状態)とはことなり、Azure AD B2Cのフローの中でエラーメッセージが表示され、フローが停止します。



どちらが良いかはシナリオ次第ですが、デバッグ時はこちらのモードを使ったほうがわかりやすいかもしれませんね。


2021年4月6日火曜日

Azure AD Verifiable Credentialsがやってきた(Public Preview)

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

ようやく出ました、Azure AD Verifiable CredentialsのPublic Preview。


AlexのBlog

https://techcommunity.microsoft.com/t5/azure-active-directory-identity/announcing-azure-ad-verifiable-credentials/ba-p/1994711


各種リソース

https://www.microsoft.com/en-us/security/business/identity-access-management/verifiable-credentials

某社もソリューションパートナーになってます。

この辺りからチュートリアルも触れるのでガシガシ触っていけると面白いと思います。

Microsoft Authenticatorを最新版にアップデートするとこんな感じでVerifiable Credentialsをどんどん発行していけます。これで各種デジタルな証明書を持ち運んでIdPにアクセスすることなくVerifierへ証明書を提示していくことができるようになるはずです。




2021年3月17日水曜日

[Azure AD B2C]遂にカスタムドメインがやってきた

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


おそらくAzure AD B2Cユーザ最大の要望だったカスタムドメイン(b2clogin.comのサブドメインではなく持ち込みのドメイン)がようやくパブリック・プレビューになりました。

参考)b2clogin.comのサブドメインをカスタムドメインと言っていた頃の記憶


当時もコレジャナイ感を感じつつ、Azure AD B2Cを使っているはずのレアル・マドリードのサイトを見ると自前ドメインを使ってるやん、、的な羨望の眼差しを抱えつつ実案件ではUSまで押しかけてプライベート・プレビューとして個別にカスタムドメインをアンロックしてもらったり、と苦労していたものです。。。


この苦労は当然世界共通で、中にはWeb Appをフロントにたててrewriteを使って無理矢理カスタムドメインを実現してしまう猛者まで現れる、という状態でした。

(ちなみにこの方法、当然のことながら可用性は落ちますし、Identity Protectionを使ったクライアント判定もできなくなるのでオススメはできません)



ということで、ようやくパブリック・プレビューです。

https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/custom-domain?pivots=b2c-custom-policy


仕組みとしては、Azure Front DoorをAzure AD B2Cの手前においてURLのRewriteする、という形です。ってこれ、上で紹介した猛者のやってた技をオフィシャルに実装した、という感じなんですね。

Identity Protectionなどはちゃんと効くのか、などはおいおい深堀りしてみるとして、まずはファーストルックです。


大まかな手順としては、

  1. Azure AD B2Cの実体となっているAzure ADにカスタムドメインを追加する
  2. Azure Front Doorを作り、b2clogin.comへ振り分け設定をする
  3. Azure Front Doorにカスタムドメインを設定する
という流れです。


順に確認してみましょう。

1. Azure AD B2Cの実体となっているAzure ADにカスタムドメインを追加する

ご存知の通り、Azure AD B2Cには実体となっているAzure ADが存在します。ポータルからAzure AD B2Cを立ち上げると、別のテナントが開き、その中でAzure AD B2Cの管理を行う、という形になります。この別テナントにもAzure ADが存在しているので、Azure AD B2Cの管理画面からテナントを変えずにAzure Portalのホームへ遷移、改めてAzure ADの管理メニューを開くと実体の管理ができるようになります。(分かりにくいですね)

そのテナントは通常のAzure ADなのでカスタムドメインを追加することができます。


ここで普通にカスタムドメインを追加し、ドメインの所有権の確認を行います。

これで第1段階はOKです。


2. Azure Front Doorを作り、b2clogin.comへ振り分け設定をする

次はAzure Front Doorを作って構成します。

Azure Front Doorは単純なエッジで動くレイヤ7のフロントサービスで、SSLのオフロードなどを含め高スケーラビリティなWebアプリをデプロイするのに役に立つサービスです。

必要な設定は、

  • フロントエンド設定(リクエストを受けるドメイン)
  • バックエンド(振り分け先となるWebアプリケーション)
  • 振り分けルール(パスやポートなど、バックエンドへの振り分け条件の設定)
の3種類です。

まずはフロントエンドです。この段階では適当な名前でAzure Front Doorドメイン(azurefd.net)上の名前を定義します。※どっちみち後でカスタムドメインをつけるので適当でOK、っていうことです。


次にバックエンドです。今回はAzure AD B2Cがバックエンドとなりますので、カスタムドメインを使いたいAzure AD B2Cのテナントドメイン名(xxx.b2clogin.com)を設定します。

最後が振り分けルールです。

ここでは特に考えずにフロントとバックエンドをストレートにマッピングしておきます。

ここもカスタムドメインを追加した後でちゃんと設定しますので仮でOKです。

これでAzure Front Doorの基本設定は完了です。


3. Azure Front Doorにカスタムドメインを設定する

次はAzure Front Doorにもカスタムドメインを設定します。ここで設定するドメインは先にAzure ADに設定したドメインと同じものを使う必要があります。

Azure Front Doorのフロントエンドまたはドメインよりカスタムドメインを追加します。

CNAMEの設定と検証が走るので必要なレコードをDNSサーバ上に設定する必要がありますが、設定としては単純にカスタムドメインを追加するだけです。


正常にドメインが追加できたら、振り分け規則についてもカスタムドメインの設定を行います。フロントエンドまたはドメインの設定より追加したカスタムドメインを選択するだけなので特に難しいことはありません。


とりあえず設定関係はこれで完了です。

(ちなみにSSL証明書もAzure Front Door側が勝手に設定するので別途買う必要はありません)

ただ、忘れがちな点が何点かあります。

  • カスタムHTMLをAzure Storage上に配置している場合はCORS設定を行う
  • redirect_uriや各種エンドポイントのアドレスも当然変わるので外部IdPなどに設定してあるredirect_uriやアプリに設定してあるエンドポイントアドレスを修正する

カスタムHTMLを使っている場合のCORS設定

外部IdP(LINEの例)のredirect_uriの追加



これで本当に設定完了です。


試してみる

とりあえず適当なアプリの設定を変えたらログイン要求をしてみます。



ちゃんとカスタムドメインで動きます。

id_tokenの中のIssuerのURIも変わっていることが分かります。


特にむずかしいことはなく、問題なく動きました。


とはいえ気になる点は何点か。
  • Identity Protectionなどフロントの環境を取得して動くサービスやカスタムポリシーの要求リゾルバはちゃんと動くのか?
  • カスタムドメインを設定しても、https://カスタムドメイン/xxx.onmicrosoft.com(もしくはテナントID)となってしまうのをhttps://カスタムドメインだけにできないか?(ルール設定でなんとかなる気もしなくもない)
  • SAML IdPとしてAzure AD B2Cをつごかす場合のIdPのEntityIDも変わっちゃう?
などなど。


引き続き試してみようと思います。











    2021年1月17日日曜日

    MATTRの分散型IDプラットフォームを触ってみる - その2

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

    前回に引き続きMATTRの分散型IDプラットフォームを触ってみます。

    前回はプラットフォーム自体のセットアップとIssuer DID、VC(Verifiable Credential)の設定までを行いましたので、今回はWalletに対して実際にVCを発行するところまでをやってみます。

    MATTRの基本的な考え方としては、バックエンドのプラットフォーム自体は認証やユーザ管理の機能を持たず外部のIdentity Providerと連携したIssuerを通じてVCを発行する、という形となっています。

    公式ドキュメントではAuth0と連携したIssuerを作成し、VCを発行する仕組みが紹介されていますので、まずはこれをやってみたいと思います。

    やるべきことは以下の3つです。

    • 外部OpenID Providerの構成
    • 外部OpenID Providerと連携したIssuerの定義を作成
    • 出来上がったIssuerでの発行リクエストをQRコードにしてWalletで読み取りVCを発行

    順番にやっていきましょう。

    外部OpenID Providerの構成

    先に触れた通り、Auth0を使って構成します。
    (ちなみに、Azure AD B2Cで構成しようとするとwell-knownまでのパスが深すぎてMATTR側でInternal Server Errorが出ます。リバプロなどでAzure AD B2Cをカスタムドメイン化して動かしてあげる必要があります。これは別のポストで今後紹介していこうと思います)

    Auth0は普段使っているテナントがそのまま使えるので特に問題はありません。
    やるべきことは、
    • アプリケーション(Client)を作成する
    • ユーザに発行すべきcredentialの型と値を属性として持たせる

    の2点だけです。

    まずはアプリケーション登録ですが、通常のRegular Web Applicationとしてクライアント定義をしていきます。


    MATTR側に設定するために必要なのはclient_idとclient_secretのみなのでアプリケーションを作成したこれらの値をメモしておきましょう。

    ちなみにredirect_uriについてはMATTR側でIssuer定義を行うと生成されますのでここでは設定しなくてもOKです。


    次にユーザに必要な属性を設定します。これもAuth0側の設定となりますが、該当のユーザを開き、user_metadataとして属性と値を設定します。サンプルに従いこんな感じに設定します。

    {
      "educationalCredentialAwarded": "Almuni 2020"
    }
    


    一旦はOpenID Provider側の設定はおしまいです。

    Issuerの作成

    次はMATTRのAPIを使って先のOpenID Providerと連携したIssuerの定義を行います。
    やるべきことは、以下のデータを設定したJSONをエンドポイントにPOSTするだけです。
    • 前回のPOSTで生成したIssuer DID
    • 先に取得したclient_id、client_secret、OPのurl(内部的に.well-knownを取得しにいくのでドメイン名の部分まで)
    • 属性のマッピング
    この辺りはMicrosoftの仕組みとほぼ同じですね。Rulesの定義の仕方もDIF(Decentralized Identity Foundation)で仕様化をしようとしているので、今後は統一されてくるのかもしれませんが。

    以下がサンプルに書いてあるIssuer作成のリクエストです。

    curl --request POST \
      --url https://tenant.platform.mattr.global/oidc/v1/issuers \
      --header 'Accept: application/json' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer REPLACE_ACCESS_TOKEN' \
      --data '{"credential": {
                 "issuerDid": "did:key:z6MkjBWPPa1njEKygyr3LR3pRKkqv714vyTkfnUdP6ToFSH5",
                   "name": "University Attendance Credential",
                   "context": [
                     "https://schema.org"
                   ],
                   "type": [
                     "AlumniCredential"
                   ]
               },
               "federatedProvider": {
                   "url": "https://example-university.au.auth0.com",
                   "scope": [
                     "openid",
                     "profile",
                     "email"
                   ],
                   "clientId": "vJ0SCKchr4XjC0xHNE8DkH6Pmlg2lkCN",
                   "clientSecret": "QNwfa4Yi4Im9zy1u_15n7SzWKt-9G5cdH0r1bONRpUPfN-UIRaaXv_90z8V6-OjH"
               },
               "claimMappings": [
                   {
                     "jsonLdTerm": "alumniOf",
                     "oidcClaim": "alumni_of"
                   }
               ]
              }'
    

    結果、CallbackUrlを含むIssuerの設定情報が返ってくるので、この値をAuth0側のアプリケーション設定に追加します。

    小さくてわかりにくいですが、Response Bodyの中にCallbackUrlが見えます。


    WalletへVCを発行する

    ここまででVC発行の準備は整いましたので、Walletアプリを使ってVC発行要求を読み込んでみます。

    発行要求はこんなURLになるので、適当にQRコードにしてMATTRモバイルアプリで読み込ませます。
    openid://discovery?issuer=https://tenant.platform.mattr.global/oidc/v1/issuers/983c0a86-204f-4431-9371-f5a22e506599
    ※この最後のIDは先に生成したIssuerのIDです。


    QRコードを読み取ると左端の画像のようにCredential Offerとして表示され、ProceedをタップするとAuth0のログオンが要求され、成功するとCredentialを受け取流ことができます。



    発行されたVCはこんな感じで中身の確認ができます。


    全体に結構簡単でした。

    今後はMicrosoftのVC基盤との連携や連携するID基盤としてAzure AD B2Cを使う、などのカスタマイズを入れていこうと思いますので、ネタが溜まってきたらまたご紹介させていただこうと思います。


    2021年1月16日土曜日

    MATTRの分散型IDプラットフォームを触ってみる - その 1

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

    ここ数年、uPort〜Microsoft VC as a Serviceなど分散型ID(DIDs/VCs*)に絡んでいるわけですが、一昨年秋のIIWに参加したときにPoCの話を聞いたMATTRのプラットフォームがかなりいい感じに進化していたので触ってみました。

    * DIDs: Decentralized Identifiers

    * VCs: Verifiable Credentials


    MATTRについて

    会社自体についてはそこまで詳しく知りませんが、ニュージーランドの会社です。

    この辺りこの辺りでは有名ですね。

    現在、MATTRが提供しているのはプラットフォームと関連する開発ツール群のようです。

    プロダクトページより)


    MATTR Platformについて

    プラットフォームはコア機能として、

    • DID
    • Messaging
    • Verifiable Credentials
    • Verifiable Presentations
    に関する生成、取得、削除、検証に関する機能群を提供しています。

    また、拡張機能として、
    • OIDC Bridge
    • White Label Mobile Wallet & SDKs(提供予定)
    が、ロックイン回避のために以下の機能もあらかじめ提供しているようです。
    • 複数のDID Methodのサポート
    • Secure Storageのサポート
    • プラガブルなKey Managementのサポート
    IIWではOIDC Bridgeの部分のデモを見せてもらいました。
    当時、私はuPortとAzure AD B2CとLibJeIDを組み合わせて免許証をトラストアンカーにしたuPort Credentialを発行、B2BのWebサイトでの身元確認を行う、というようなデモを作ったりしていました。懐かしい。


    開発ツールについて

    プラットフォーム以外にも開発者向けに以下の機能が提供されています。
    • MATTR Mobile Wallet App
    • Sample Applications
    • MATTR Command Line Interface(提供予定)


    今回、プラットフォームのコア部分に関するSandbox環境を払い出してもらったので少し触ってみます。

    では、早速レビューを。

    トライアル申し込みをする

    まずは環境をもらうところからですが、先程のプロダクトページの一番下にSandbox環境のトライアル申し込みがあるので申し込んでみました。

    しばらくするとメールとSlackへの招待がくるので、Slackで担当の方と会話をすることになります。基本的にはKeybase上でトライアルテナントの情報とかシークレットなどを渡すからまずはKeybaseのアカウントを教えるように言われるのでアカウント名を伝えます。
    (Keybaseのアカウントを作るところから始めました)

    アカウントを伝えると今度はKeybaseのチャットで担当の人から以下の情報をもらえます。
    • tenantSubdomain: xxxx.sandbox.platform.mattr.global
    • tenantId: xxx-xxx-xxx
    • url: https://mattr-prod.au.auth0.com/oauth/token(Auth0使ってるんですね)
    • audience: https://platform.mattr.global
    • client_id: xxxxxxxxxxx
    • client_secret: xxxxxxxxxxx

    プラットフォームの設定を行う

    先にもらった情報があるとプラットフォームにアクセスできるようになります。(といってもAPIだけしか存在しないので、APIを叩きまくるんですが)

    詳細は
    に手順がのっているのでこちらをみながら進めます。

    API Auth Tokenを取得する

    要するに、先程Keybaseで伝えられたclient_idやclient_secretはAuth0のプラットフォームでaccess_token(MATTRプラットフォームのAPI Auth Token)を取得するためのものだったわけです。
    普通にclient_credentialsでaccess_tokenを取得します。

    curl --request POST \
      --url https://mattr-prod.au.auth0.com/oauth/token \
      --header 'Content-Type: application/json' \
      --data '{"client_id": "xxxxxxxxxx",
               "client_secret": "xxxxxxxxxx",
               "audience": "https://platform.mattr.global",
               "grant_type": "client_credentials"
              }’
    

    DIDを生成する

    まずはDIDを生成してます。
    methodとしてはkey、web、sovの3種類をサポートしているようです。
    didのエンドポイントにAPI Auth Tokenをつけて生成リクエストをPOSTするだけなので非常にシンプルです。
    curl --request POST \
      --url https://tenant.platform.mattr.global/v1/dids \
      --header 'Accept: application/json' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer REPLACE_ACCESS_TOKEN' \
      --data '{   "method":"key",
                  "options": {
                      "keyType":"ed25519"
                  }
              }'

    うまくいくとDID Documentが返ってきます。
    MATTRのResolver APIもありますが、Universal Resolverでもちゃんと解決できるようになります。

    Issuerに関する情報を確認する

    DIDを発行することでIssuerのDID構成情報を確認することができるようになります。DIFのWell Known DID Configurationのスペックに対応しているようです。

    curl --request GET \
      --url https://tenant.platform.mattr.global/.well-known/did-configuration \
      --header 'Accept: application/json'
    

    結果、IssuerのDID構成情報が確認できます。

    VCを発行する

    こちらもAPIが用意されていますので、IssuerのDID、SubjectのDID、VCに含めるClaimなどを決めてPOSTしてあげるだけです。
    curl --request POST \
      --url https://tenant.platform.mattr.global/v1/credentials \
      --header 'Accept: application/json' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer REPLACE_ACCESS_TOKEN' \
      --data '{"@context":["https://www.w3.org/2018/credentials/examples/v1" , "https://www.w3.org/2018/credentials/v1"],
               "subjectId":"did:key:z6MkjBWPPa1njEKygyr3LR3pRKkqv714vyTkfnUdP6ToFSH5",
               "type":["AlumniCredential"],
               "claims":{"givenName":"Jamie",
                         "familyName":"Doe",
                         "alumniOf":"Example University"},
               "issuer":{"id":"did:key:z6Mkg7FkYxUpSKBEUJMeG91A9vz66GfWxB4m9Lq81AMZ7wNT",
                         "name":"Example University"},
               "persist":true,
               "revocable":true
              }'
    

    ありがちな卒業生である証明を発行するサンプルですね。

    発行したVCは同じAPIのエンドポイントにGETしてあげると一覧表示されます。

    とりあえず最低限必要な機能はちゃんと動いていますし、他にもVCのRevokeなど管理系のAPIも充実している感じです。

    Walletアプリも使えるようにしてもらったので、次回はOIDC Bridgeと合わせてWalletへのVP/VC発行とOIDC-DID Authのゲートウェイでのログインなどチュートリアルにそって試してみようかと思います。

    2020年12月17日木曜日

    OpenID Connectの脇役たち

    本記事は Digital Identity技術勉強会 #iddance Advent Calendar 2020 17日目の記事です。


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

    今日は年末ということもあり、普段はあまり表舞台に出てこないOpenID ConnectのOptionalなオプションにフォーカスを当ててみようかと思います。
    対象とする仕様は「OpenID Connect Core 1.0」とします。


    OpenID Connectの設計思想

    OpenID ConnectはいわゆるID連携(Federation)を行うための仕様として、OAuth2.0の上位にアイデンティティ層を載せる形で定義されています。

    そして、その設計思想は、
    • 簡単なことは簡単に
    • 難しいことも可能に
    • モジュラーデザイン
    という原則に則っています。

    この中の最初の原則である「簡単なことは簡単に」という部分が普段みなさんが使っているOpenID Connectを使ったログオンの実装の大半で、上記の仕様の第2章「Authentication」に定義されているAuthorization code flow、Implicit flow、Hybrid flowの3つ、特にAuthorization code flowを覚えておけば基本的なWebアプリケーションへのログインのシナリオでは何も難しいことはありません。
    ※当然、セキュリティ上の考慮事項などはそれなりに存在するため、stateやnonceを正しく使ってcodeを横取りされたりid_tokenを使いまわされることを防いだりする必要はありますので運用環境で使うためにはちゃんと仕様を理解して実装する必要はありますが。。。

    また、2つ目の「難しいことも簡単に」、3つ目の「モジュラーデザイン」の原則の通り、OpenID Connect DiscoveryやOpenID Connect Dynamic Client Registrationなど関連仕様との組み合わせでより高度なシナリオにも対応することができるようになっています。

    今回はニッチを狙いますので、OPTIONALなパラメータを重点的に見ていきたいと思います。

    RFCにおける要求レベルの定義

    仕様を読んでいるとMUST、SHOULD、MAY、OPTIONALなど各パラメータ毎に要求レベルが定義されています。
    この要求レベル自体はRFC2119で以下の通り定義されています。
    ※RFC2119の日本語訳はIPAのホームページで公開されています。

    以下、IPAの日本語訳です(赤字・太字は筆者)。
    1. 「しなければならない( MUST )」 
      • この語句、もしくは「要求されている( REQUIRED )」および「することになる( SHALL )」は、その規定が当該仕様の絶対的な 要請事項であることを意味します。
    2. 「してはならない( MUST NOT )」
      • この語句、もしくは「することはない( SHALL NOT )」は、その規定が当該仕様の絶対的な禁止事項であることを意味します。
    3. 「する必要がある( SHOULD )」
      • この語句もしくは「推奨される( RECOMMENDED )」という形容表現は、 特定の状況下では、特定の項目を無視する正当な理由が存在するかもしれませんが、 異なる選択をする前に、当該項目の示唆するところを十分に理解し、 慎重に重要性を判断しなければならない、ということを意味します。
    4. 「しないほうがよい( SHOULD NOT )」 
      • この語句もしくは「推奨されない( NOT RECOMENDED )」という形容表現は、 特定の動作が容認できる、ないし、非常に有用である、というような 特定の状況下では、正当な理由が存在するかもしれませんが、 このレベルの動作を実装する前に、当該項目の示唆するところを十分に理解し、慎重に重要性を判断しなければならない、ということを意味します。
    5. 「してもよい( MAY )」 
      • この語句、もしくは「選択できる( OPTIONAL )」という形容表現は、ある要素が、まさに選択的であることを意味します。 その要素を求めている特定の市場があるから、あるいは、 他のベンダーはその要素を提供しないだろうが、その製品機能を拡張する と察知して、その要素を含む選択をするベンダーがあるかもしれません。 特定の選択事項(オプション)を含まない実装は、おそらく機能的には劣る ことになるでしょうが、そのオプションを含む他の実装との相互運用に備えなければなりません( MUST )。 同様に、特定のオプションを含む実装は、そのオプションを含まない実装 との相互運用に備えなければなりません( MUST )。(当然ながら、そのオプションが提供する機能は除かれます。)

    まさに今回のターゲットはMAY、もしくはOPTIONALな部分です。

    MAYとOPTIONALを仕様から抽出する

    早速、仕様の中にどのくらいMAYとOPTIONALがあるのか抽出してみます。
    • MAY:87個
    • OPTIONAL:53個
    ・・・結構ありますね。

    全部カバーしているとキリがないので、独断と偏見でMAY/OPTIONALを5個選んで番付的に紹介してみようと思います。
    ※もちろんOPTIONALなので実装しているOpenID Providerばかりではありませんので、動かしてみても期待する反応がえられないケースが多いので悪しからず。

    十両:prompt

    認証リクエストにpromptパラメータを付加することで再認証や同意を求めることができます。

    仕様では3.1.2.1のAuthentication Requestの項に定義されています。(OpenIDファウンデーションジャパンの日本語訳から引用)
    OPTIONAL. Authorization Server が End-User に再認証および同意を再度要求するかどうか指定するための, スペース区切りの ASCII 文字列のリスト. 以下の値が定義されている.
    none
    Authorization Server はいかなる認証および同意 UI をも表示してはならない (MUST NOT). End-User が認証済でない場合, Client が要求する Claim 取得に十分な事前同意を取得済でない場合, またはリクエストを処理するために必要な何らかの条件を満たさない場合には, エラーが返される. 典型的なエラーコードは login_requiredinteraction_required であり, その他のコードは Section 3.1.2.6 で定義されている. これは既存の認証と同意の両方, またはいずれかを確認する方法として使用できる.
    login
    Authorization Server は End-User を再認証するべきである (SHOULD). 再認証が不可能な場合はエラーを返す (MUST). 典型的なエラーコードは login_required である.
    consent
    Authorization Server は Client にレスポンスを返す前に End-User に同意を要求するべきである (SHOULD). 同意要求が不可能な場合はエラーを返す (MUST). 典型的なエラーコードは consent_required である.
    select_account
    Authorization Server は End-User にアカウント選択を促すべきである (SHOULD). この prompt 値は, End-User が Authorization Server 上に複数アカウントを持っているとき, 現在のセッションに紐づくアカウントの中から一つを選択することを可能にする. End-User によるアカウント選択が不可能な場合はエラーを返す (MUST). 典型的なエラーコードは account_selection_required である.
    prompt パラメータは Client に対して, End-User のセッションがアクティブであることを確認したり, End-User にリクエストに対する注意を促すことを可能にする. none がその他の値とともに用いられる場合はエラーとなる.

    アプリの仕様でトランザクションの種類によって強制再認証を求めたり、同意を求めたりするケースもあると思うので、そのような場合はうまくpromptパラメータを使うと良いですね。

    前頭:target_link_uri

    SAMLでいうrelayStateですね。

    仕様にも記載がありますが、全てのログインフローがRelying PartyからOPへのリクエストによって始まるわけではなく、OP起点だったり別のシステム(ポータルなど)から起動されることもあります。そのような場合、ログインフローを起動するシステムはRPのログイン開始エンドポイントへユーザをリダイレクトしてフローを起動するわけですが、ログインが完了した後、必ずしもRPのデフォルトのランディングページに着地させたいわけではなく、別のページへ飛ばしたい、というケースもあります。そのような場合にtarget_link_uriに指定するとログイン完了後に望むページへ遷移させることができます。

    ただ、注意点として記載がある通りOpenリダイレクタにならないように指定できるURLはきちんと検証しないといけません。

    仕様では4のInitiating Login from a Third Partyの項に定義されています。(OpenIDファウンデーションジャパンの日本語訳から引用)
    target_link_uri
    OPTIONAL. 認証後, RP がリダイレクトするよう要求された URL. RP は外部サイトへのオープンリダイレクターとして使用されることを防ぐために target_link_uri の値を検証しなければならない(MUST).
    SAMLを使ったシステム導入の際はrelayStateに関する要望は結構あったので、今後このパラメータもメジャーになってくるかな?と思います。

    関脇:request/request_uri

    いわゆるRequest Objectです。FAPI Part2では認可要求自体への署名が要求されるので、普通にQuery Stringに各種リクエストパラメータをくっつけるのではなく、JWTとして認可サーバへ渡してあげる必要があります。また認可要求にJWTそのものを渡すこともできますが、request_uriに指定したエンドポイントを参照させることによりリクエストパラメータを取りに来てもらうこともできます。

    仕様では6のPassing Request Parameters as JWTsの項に定義されています。(OpenIDファウンデーションジャパンの日本語訳から引用)
    request
    OPTIONAL. このパラメータにより, OpenID Connect リクエストを単一の self-contained なパラメータとすることができ, 任意で署名および暗号化を施せるようになる. パラメータ値は Request Object 値である (Section 6.1 参照). Request Object は, 各 Claim がリクエストパラメータとなる JWT である.
    request_uri
    OPTIONAL. このパラメータにより, 値そのものではなく参照を送ることが可能になる. request_uri 値は https スキーマで始まる URL であり, Request Object 値を含むリソースへの参照となる. 参照先の Request Object は, リクエストパラメータを含む JWT である.
    金融サービスに限らず要求についても隠蔽したいケースや署名をつけて確実に渡したいケースではこのパラメータは活躍する場面がありそうです。

    大関:id_token_hint

    完全に個人的な趣味です。実はAzure ADを使っていると結構活躍の機会が多いんです。例えば今はもう新規のサポートは受け付けていませんがPremium P2の機能のカスタムMFAプロバイダへのセッション引き継ぎはid_token_hintを使って行っていましたし、そもそもOffice365→Azure AD→外部IdPというようなチェーン構成のフェデレーションでは前段で入力されたユーザ名のドメインパートに基づきログイン先のIdPを動的に変更する、なんということもよくやります。そのようなケースでは前段のIdPでのユーザの挙動(入力した値や、その値から導き出された値など)を連鎖する後段のIdPにも伝えないと、ユーザ名を2回入力する必要が出てきたり、とUXを毀損してしまいがちです。

    このようなケースではid_token_hintの中に必要なパラメータを詰め込んで後段のIdPへJWTとして渡してあげることで格段にUXが向上します。
    (Office365のケースではOpenID Connect→ws-federationの連鎖なのでusernameというパラメータを使っていますが)

    仕様では3.1.2.1のAuthentication Requestの項に定義されています。(OpenIDファウンデーションジャパンの日本語訳から引用)
    id_token_hint
    OPTIONAL. Authorization Server が以前発行した ID Token. Client が認証した End-User の現在もしくは過去のセッションに関するヒントとして利用される. もしこの ID Token に紐づく End-User が認証済, もしくはこのリクエスト中で認証された場合, Authorization Server はポジティブレスポンスを返す. さもなければ, Authorization Server は login_required のようなエラーを返す (SHOULD). prompt=none を利用する場合は, 可能であれば id_token_hint を指定するべきであり (SHOULD), さもなければ invalid_request を返しても良い (MAY). ただしサーバーはその場合可能な限りサクセスレスポンスを返すこと. id_token_hint 利用時は, ID Token の audience に Authorization Server 自身が含まれている必要はない.
    id_token_hint として使用するために RP によって受信された OP からの ID Token が暗号化されていた場合, クライアントは暗号化された ID Token を含んだ署名済みの ID Token を復号しなければならない (MUST). クライアントは Authentication Server に送信する署名済みの ID Token をサーバーが ID Token を復号できる鍵を用いて再暗号化し, id_token_hint の値として使用してもよい (MAY).

    横綱:claims

    最後の横綱級はなんといってもclaimsでしょう。理由はシンプルで私も共同議長を勤めさせていただいるOpenID FoundationのeKYC and Identity Assurance WGで策定中のOpenID Connect for Identity Assuranceの仕様はclaimsがあるから成り立っている、といっても過言ではないからです。

    パラメータの意味合いとしてはRPからOPへの認証要求時にclaimsに指定した属性をid_tokenもしくはuserInfoとして提供することを明示的に求める、というものです。OpenID Connect for Identity Assuranceではこの機能を拡張してRPがOPに検証済みの属性を要求する、ということを実現しています。

    仕様では5.5のRequesting Claims using the "claims" Request Parameterの項に定義されています。(OpenIDファウンデーションジャパンの日本語訳から引用)
    claims
    OPTIONAL. 当パラメータは, 特定の Claim の返却を要求するのに用いられる. 値は要求する Claim をリスト化した JSON オブジェクトである.

    claims Authentication Request パラメータは, 特定の Claim を UserInfo Endpoint から, かつ/または ID Token 内で, 返却することを要求する. これは要求する Claim のリストを含む JSON オブジェクトとして表される. 要求する Claim のプロパティが指定されていてもよい (MAY).

    claims パラメータのサポートは任意である (OPTIONAL). 当パラメータをサポートしない OP に対して RP が当パラメータを使用したとき, OP は 適切と思われるヒューリスティックな方法を用いて, RP と End-User にとって有益と思われる Claim のセットを返すべきである (SHOULD). Discovery で得られる claims_parameter_supported は, OP が当パラメータをサポートしているかどうかを示す.

    claims パラメータ値は, OAuth 2.0 要求の中で, UTF-8 でエンコードされた JSON として表される (最終的には OAuth パラメータとして受け渡されるときに form-urlencoded される). Request Object 値として使用される際は, Section 6.1 により, JSON が claims メンバーの値として使用される.

    Claim 要求 JSON オブジェクトのトップレベルメンバーは以下の通り:

    userinfo
    OPTIONAL. UserInfo Endpoint へ返却を要求する個々の Claim のリストを示す. 当メンバーが存在した場合, scope 値で要求された Claim に加え, 当メンバーでリストされた Claim も返却される. 当メンバーが存在しなかった場合, scope 値で要求された Claim のみが返却される.
    userinfo メンバーを指定する際は, UserInfo Endpoint を使用するために, response_type に対し, Access Token を Client に発行するタイプの値を指定しなければならない (MUST).
    id_token
    OPTIONAL. ID Token 内に格納して返却を要求する個々の Claim のリストを示す. 当メンバーが存在した場合, デフォルトの Claim に加え, 当メンバーでリストされた Claim も返却される. 当メンバーが存在しなかった場合, デフォルトの Claim のみが返却される. デフォルトの Claim 等の ID Token の定義については Section 2を, フロー毎の ID Token 要件については Section 3.1.3.63.2.2.103.3.2.113.3.3.6 を参照すること.

    上記以外のメンバーが存在してもよい (MAY). 認識できないメンバーが使用された場合は無視しなければならない (MUST).


    通常のOPでclaimsを利用している実装ってあまり見かけないのですが、先日某芸能事務所のファンクラブサイトに娘がログインするところをトレースしていたらclaimsを使っているのが判明し驚愕しました(w)
    ちなみになぜclaimsを使っているのかはよくわかりません。。。自前RPと自前OPのはずなのでこんなことをしなくてもOPが必要な属性をid_tokenやuserInfoに入れて返してあげれば済むと思うのですが・・・



    いかがでしたか?
    他にもご紹介したいニッチなパラメータもいっぱいあるので、また機会があればご紹介できればと思います。