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

2024年5月10日金曜日

Entra IDの外部認証プロバイダの設定を試す(1)

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

先日当Blogにも書いたとおり、最近Previewが公開されたEntra IDの外部認証を少しずつ試していきます。

設定はこの辺りのドキュメントを見ればできそうです。

https://learn.microsoft.com/ja-jp/entra/identity/authentication/how-to-authentication-external-method-manage


ざっとやり方と条件を見ていくと、こんな感じっぽいです。

  • Entra ID上にマルチテナントアプリとして外部認証システムをクライアント登録する
  • 外部認証システムがEntra IDが発行したid_token_hintを検証できるようにEntra IDのDiscoveryエンドポイントを解釈できるように構成する
  • 外部認証システムへEntra IDをクライアント登録する
  • 外部認証システムの認証強度の要求はclaimsパラメータを利用し、amr/acrの値が要求される。そのため外部認証システムは指定された値のamr/acrを返却できるように構成する必要がある
  • 外部認証システムの認可エンドポイントへのアクセスはPOSTで行われる
  • 外部認証システムからEntra IDへのid_tokenの引渡しはform_postを使う必要がある

まだ細かいところは色々とありますが、やりながら潰していきましょう。

しかしまぁ、結構条件厳しめですね。やはり自作IdPをカスタマイズしつつ対応させていくのが良さそうです。


と言うことで徐々に試します。今回は外部認証システムへ認証要求が飛ぶところまでを見ていきます。

マルチテナントアプリの登録

まずはEntra IDに外部認証システムを登録してあげる必要があります。ログイン前に参照することが必要になる、かつ他のマルチテナントアプリに対して認証する可能性があることから、外部認証システム自体の登録もマルチテナントアプリとしてクライアント登録を行います。

この際、redirect_uriには外部認証システムの認可エンドポイントのURLを指定する必要があります。

次に、APIアクセス許可を行います。

Microsoft Graphへのアクセス許可をする(委任されたアクセス許可)必要があります。

対象の権限にはopenidとprofileを指定します。

管理者の同意を付与しておきます。


外部認証の設定を行う

いよいよ外部認証システムの登録を行います。
  • 名前は適当でも良いのですが後から変えられないので注意が必要です。
  • クライアントIDは外部認証システム側にEntra IDを登録する際に発行されるクライアントIDを指定します。(次回以降で外部認証システム側への登録の話をします)
  • 検出エンドポイントには外部認証システムのdiscoveryエンドポイントを指定します。
  • アプリIDは先ほどEntra ID上に登録したマルチテナントアプリのクライアントIDを指定します。

また、この認証方式を使うことができるユーザが所属するグループを指定し、設定を有効にして保存します。

動作を確認する

この状態でユーザでログインをする際に多要素認証が求められるように設定しておくと、認証方式として先ほど指定した方式が出てきます。(出てこない場合はMicrosoft Authenticatorが現在使えない、というリンクをクリックすると出てきます)

こちらを選択すると、外部認証システムへリダイレクトされるのですが、トレーサーでリクエストを見ると以下のように認可エンドポイントへPOSTでid_tokenやclaimsを含んだリクエストが飛んでいることがわかります。

id_token_hintを紐解くとこんな感じです。

おすすめは外部認証システム側にoid(オブジェクトID)とtid(テナントID)を紐づけた形でユーザを作成しておき、当該のユーザで認証することです。(preferred_usernameだと変わってしまう可能性があるので)

また、認証方式・強度などに関する要求はclaimsパラメータで指定がされていますので、外部認証システムはこの条件を満たす形で認証を行い、id_tokenのacr/amrに値を含めてEntra IDへ送出してあげる必要があります。 

{
"claims": {
"id_token": {
"amr": {
"essential": true,
"values": [
"face",
"fido",
"fpt",
"hwk",
"iris",
"otp",
"tel",
"pop",
"retina",
"sc",
"sms",
"swk",
"vbm"
]
},
"acr": {
"essential": true,
"values": [
"possessionorinherence"
]
}
}
}
}

次回以降は外部認証システム側の設定を調整していきたいと思います。

 



2024年5月8日水曜日

Entra IDの外部認証プロバイダの利用機能がPreview公開されています



Entra IDで外部の認証手段が使えるようになったようです。

むかーし、3rdパーティの多要素認証プロバイダの設定を行う機能が一瞬出て消えていったものの後継ですね。当時はPremium P2ライセンスが必要でDuoやRSA、Trusonaなどプリセットされたものを認証プロバイダとして利用することができました。
当時の記録

まぁ、中身はid_token_hintを使ってIdPをチェインさせているだけだった気がしますが、当時はあんまり流行らなかったんですかね・・・。

今回のアナウンスとドキュメントを見ているとやはりid_token_hintを使った認証状態の引き回しとチェインであることには変わらなさそうですが、より柔軟に構成を行うことができるようになっていますね。ライセンスもPremium P1でOKっぽいですし。

ということで私のテナントでも機能が有効になったのでおいおい試してみたいと思います。


2024年5月3日金曜日

Entra External IDがGAされています

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

長らくPreviewだったEntra External ID(旧Azure AD B2B、およびCIAM)がGAされました。(といっても特にCIAMはまだまだPreviewの機能だらけなんですけどね・・・)

https://techcommunity.microsoft.com/t5/microsoft-entra-blog/announcing-general-availability-of-microsoft-entra-external-id/ba-p/3974961


個人的にポイントだと思っているのは、いわゆるワークフォースIDであるEntra ID(Azure AD)との機能面での統合が進んだこと、そしてEntra Verified IDとの連携ですね。

しかし、もうここまでくると単なるID基盤という枠には収まらず、他のAzureリソースとの組み合わせを意識した統合的なアイデンティティ・プラットフォームになってきていますね。いよいよインフラとしての設計も難しくなってきてますので、ちゃんとプロ(国井さんとか)の教育を受けて使うことをお勧めします。



個人的にも気になってきたAzure AD B2Cからのトランジションについてはまだまだ情報が不足していますが、現状のCIAMの機能ではとてもじゃないけどAzure AD B2Cの自由度のカバーはできないので、まだしばらくは並行してサポートされていくことになると思います。本社の開発チームの話ではマイグレーションパスなどもゆくゆくは用意していくということなので、こちらも継続ウォッチですね。

2022年11月6日日曜日

発行済みVerifiable Credentialsの状態確認を行うStatus List 2021の仕様と動作

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

今日はちょっとマニアックなところを。(完全に自分向けのメモです)


Microsoft Entra Verified IDは発行済みのVerifiable Credentialsの状態(有効・取り消し済み)を管理するためにDecentralized Identity Foundation(DIF)のStatus List 2021とIdentity Hubという仕様を使っています。

ちなみにその後Identity Hubはdecentralized web nodeという仕様になっているので、もうIdentity Hubの仕様はすでに古いものとなっています。

Decentralized Web Nodeの仕様


基本的にやりたいことはとしては、

  • 発行されたVerifiable Credentialの状態をHolderやVerifierは確認したい
  • ただ、Issuerに状態を問い合わせるのでは従来の集中モデルと変わらずプライバシー保護の観点などからも好ましくない
ということなので、Issuerに問い合わせしなくてもVerifiable Credentialの有効状態を確認できる必要があります。

ということでStatusList2021CredentialというタイプのVerifiable Credentialを発行し、IssuerのIdentity Hubに発行、他のノード等からIssuerが把握することなく閲覧が可能な状態を実現します。
なお、スケーラビリティへの考慮から発行済みVerifiable Credentialsのリストをなるべくコンパクトに保持する必要があり、ビット配列で状態を保持する形の仕様となっています。


今回はHolderやVerifier(主にはこちらが確認することが多いとは思いますが)などVerifiable Credentialを受け取ったエンティティがどのように有効性確認を行うのか?について触れたいと思います。(あくまで現時点でのMicrosoft Entra Verified IDでの実装をベースにしています)

■大まかな流れ

大まかにはこんな流れです。
  1. Verifiable Credentialを受け取る
  2. 受け取ったVC内のCredentialStatusを取得(主に以下2つの値が重要)
    • statusListIndex
    • statusListCredential
  3. Issuer DIDのDID DocumentからIdentity HubのserviceEndpointを取得
  4. 2で取得したstatusListCredentilalからIdentity HubへPOSTすべきBodyを生成、Identity Hubへ投げ込む
  5. Identity HubからstatusList2021CredentialというTypeのVCが返ってくるのでencodedListを取得
  6. 2でとっておいたstatusListIndexでencodedListのオフセットを確認し、ビットが立っていたら取り消し済み、倒れていたら有効として判断

■実際に取得してみる

まずは、VCからCredentialStatusの取得です。これは単純にJWTをパースすればOKです。
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1"
    ],
    "type": [
      "VerifiableCredential",
      "hogehogeVC"
    ],
    "credentialSubject": {
      "name": "hoge taro",
      "mail": "hoge@exampple.jp"
    },
    "credentialStatus": {
      "id": "urn:uuid:6fa4e682-f427-41cf-b0e5-59179d66fea3?bit-index=5",
      "type": "RevocationList2021Status",
      "statusListIndex": 5,
      "statusListCredential": "did:web:example.jp?service=IdentityHub&queries=W3sibWV0aG9kIjoiQ29...(省略)...jZmZWEzIn1d"
    },
    (以下省略)


大事なのはstatusListIndex、statusListCredentialなかでもqueriesの値です。
queriesはbase64urlエンコードされたjsonなのでデコードすると後からIdentity Hubへ投げ込む値が出てきます。
[
	{
		"method": "CollectionsQuery",
		"schema": "https://w3id.org/vc-status-list-2021/v1",
		"objectId": "6fa4e682-f427-41cf-b0e5-59179d66fea3"
	}
]


では、このデータをIdentity Hubに投げ込んでいきます。
まずはIdentity Hubのエンドポイントを取得する必要があります。statusListCredentialを見ると当該のDIDのserviceの種類がIdentityHubとなっているところにqueriesの値を投げ込むべし、ということが書いてあり、MSの仕様ではIdentityHubへ聞きに行く必要があるということが指し示されているからです。
ということでIssuer DIDをResolveします。これまでもこのBlogで触れてきたuniversal resolverを使ってもいいですし、Microsoftが用意しているdiscoveryエンドポイントを使ってもいいでしょう。今回はMicrosoftのものを使いました。
https://discover.did.msidentity.com/1.0/identifiers/{IssuerのDID}
でGETするとDID Documentが返ってきます。
{
  "id": "did:web:example.jp",
  "@context": [
    "https://www.w3.org/ns/did/v1",
    {
      "@base": "did:web:example.jp"
    }
  ],
  "service": [
    {
      "id": "#linkeddomains",
      "type": "LinkedDomains",
      "serviceEndpoint": {
        "origins": [
          "https://example.jp/"
        ]
      }
    },
    {
      "id": "#hub",
      "type": "IdentityHub",
      "serviceEndpoint": {
        "instances": [
          "https://hub.did.msidentity.com/v1.0/{tenant id}"
        ]
      }
    }
  ],
  (以下省略)

この中のIdentityHubのserviceEndpointの値を取得します。Entra Verified IDの場合、https://hub.did.msidentity.com/v1.0/{Azure ADのテナントID}という構造になっていますので、あらかじめわかっている場合はわざわざresolveしなくてもいいかもしれません。

このエンドポイントに先ほど取得したqueriesの値を含むjsonをPOSTすることでstatusList2021Credentialが取得できます。

まずはPOSTデータの作成です。
構造としてはこんな感じになっています。
{
  "requestId": "c5784162-84af-4aab-aff5-f1f8438dfc33",
  "target": "did:web:example.jp",
  "messages": [
    {
      "descriptor": {
        "method": "CollectionsQuery",
        "schema": "https://w3id.org/vc-status-list-2021/v1",
        "objectId": "6fa4e682-f427-41cf-b0e5-59179d66fea3"
      }
    }
  ]
}

requestIdはuuid-v4形式の値を指定します。単なるリクエストとレスポンスを紐づけるための識別子なので値はなんでもOKです。
targetはissuerのDIDを指定します。
messagesの中のdescriptorに先ほど取得したqueriesの値をセットします。

ということでPOSTすると以下のレスポンスが返ってきます。
{
    "requestId": "c5784162-84af-4aab-aff5-f1f8438dfc33",
    "replies": [
        {
            "messageId": "bafkreicksslcxa7xraqg6luqqfsezkpfalpqdqk6jzealwqxrkv7svu5vy",
            "status": {
                "code": 200
            },
            "entries": [
                {
                    "descriptor": {
                        "method": "CollectionsWrite",
                        "schema": "https://w3id.org/vc-status-list-2021/v1",
                        "dataFormat": "application/vc+jwt",
                        "objectId": "6fa4e682-f427-41cf-b0e5-59179d66fea3",
                        "clock": 0,
                        "cid": "bafkreib5cnsi7kw5ya6otq2lybvwnqlh2ga2gmud7x7t46f4zkkcca6s5y"
                    },
                    "data": "ZXlKaGJHY2lPaUpG...(省略)...IydDNXaWhR"
                }
            ]
        }
    ]
}

大事なのはdataの部分です。
この値はbase64エンコードされたVerifiable CredentialsなのでデコードするといつものeyJ...が出てきます。もちろんこのjwtの署名検証はするとして、中身を確認していきます。
{
  "vc": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://w3id.org/vc-status-list-2021/v1"
    ],
    "type": [
      "VerifiableCredential",
      "StatusList2021Credential"
    ],
    "credentialSubject": {
      "id": "urn:uuid:6fa4e682-f427-41cf-b0e5-59179d66fea3",
      "type": "RevocationList2021",
      "encodedList": "H4sIAAAAAAAAA-3BAQEAAAgCoPw_qmsOEfgcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAhAJmaUnkqGEAAA"
    }
  },
  "jti": "did:web:example.jp?service=IdentityHub&queries=W3sibWV0aG9kIjo3...(省略)...zlkNjZmZWEzIn1d",
  "iss": "did:web:example.jp",
  "sub": "urn:uuid:6fa4e682-f427-41cf-b0e5-59179d66fea3",
  "iat": 1667651604
}

大事なのはencodedListです。
この値はbase64でエンコードされgzipされたビット配列なのでデコードし、確認したいVCのstatusListIndexの値のオフセットの部分のビットの状態を確認します。

例えば、以下のような状態になっている場合は上から下に向けて1-2-4-8-...という形で桁が上がっていくのでこの例だと7番目だけがActive、あとは取り消し済みなのでencodedListは2進数でいうと「...110111111」という形で対応するIndexにあたるビットが立ちます。

ここまでわかればあとは簡単ですね。
statusListIndexに指定された値(上の例だと5)に該当するオフセットの部分をmaskしてANDをとれば当該ビットが立っているのかどうかがわかり、当該のVCの状態が把握できます。


ということで今回はStatus List 2021の仕様とMSの実装について触れました。
(実際はMSのAPIの中でよろしくやってくれるので自前でコードを書く必要はないんですけどね)






2022年7月2日土曜日

分散型ID関係のコミュニティ立ち上げ

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


5月末にMicrosoftからAzure Active Directory、CloudKnox Permissions Management、Azure AD Verifiable CredentialsをまとめたMicrosoft Entraが発表されたこともあり、先日のOffice365勉強会で分散型ID(DID/Decentralized Identifiers)、検証可能な資格情報(VC/Verifiable Credentials)に関するプレゼンをさせていただきました。

事前申し込みも400オーバー、当日も230名くらいの方にご参加いただき、slidoの質問やコメントも止まらない感じで時間を大幅に超えて23時くらいまでやらせていただくくらいには盛況だった様です。(みんなそんなにDIDとVCに興味あるのかな?)

また、そんな中、W3Cでは長らくFormal Objectionによるこう着状態が続いていたDID Core Specificationに決着がつきW3C勧告へ進むことが承認された、との発表がありました。

これでますます開発者の人たちは安心してこの技術領域へ突き進んでいけますね!


ということで、先の勉強会でも発表させていただいたのですが、DID/VCに興味のあるエンジニアの皆さんが集まる場が欲しいよね、ということでCollabogateの三井さんやBlockBaseの山村さんたちと「DID Developer Community(仮)」を立ち上げることにしました。


と言っても現時点ではDiscordの板が存在しているくらいなので、あまりコンテンツもありませんし、アクティブな活動も予定されているわけではありませんが、まずはここにエンジニアの皆さんには集まっていただき、なんでも情報交換ができる様な場所を作れればな、、と思います。

ということでぜひご参加ください。

https://discord.gg/nn53BRRz(招待リンクが切れていたので張り替えました)

https://discord.gg/UFE9m22TeT


あ、参考までに先の勉強会で使った資料も貼っておきます。