2020年7月23日木曜日

[DID]リゾルバあれこれ

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

完全に個人メモです。

ご存知の通りDID(Decentralized Identifier)の構造は
did:{method}:{method specific identifier}
となっています。

例えば、イーサリアムだったら
did:ethr:0xE6Fe788d8ca214A080b0f6aC7F48480b2AEfa9a6
という感じです。

現状Blockchainの系がバラバラと乱立している状態なので、系の間でユニバーサルに一意に識別できる仕組みがないとDIDがIdentifier(識別子)としての役割を果たせないことはわかるんですが、そもそも論としてメソッド名が識別子の中に入っているって言うのもなぁ、と個人的には思いますが他にいいアイデアが出せるわけではないので自粛しておきます。

話はそれましたがDIDが上記の様な形式になっている以上、系を跨いで識別子(DID)および関連する情報(DID Metadata)を解決する仕組みがないと、DIDを使ったアイデンティティ管理システムが成立しません。ということで今日の本題の「リゾルバ」が必要になるわけで、実質標準になっているのがMarcusがやっている「Universal Resolver」である、というわけです。

元々DID関係はW3CのWeb Payment WG、Verifiable Credentials TF、OASISのXDI TC Registry WGが別々にやっていて、2015年〜2016年あたりでDPKIとかのドラフトとして出てきた中でレゾルバの必要性に注目してUniversal Resolverを作った、みたいな話を2018年のEuropean Identity and Cloud ConferenceでMarkusから聞いたとき、リソルバ自身の信頼性ってどうやって担保するの??みたいな話を聞いた覚えがあります。その時にMarkusはリゾルバ自体はOSSだからプライベート実装しても良いし、アプリに組み込んでも良いよ、みたいな話をしていました。

そんな中でMarkusがサンプル実装として公開したのが先の https://uniresolver.io/ で、他にもベンダが実装してきている例としてMicrosoftが自前のDID Projectで実装したのが、 https://beta.discover.did.microsoft.com/ だったりする、ということなんですね。

と言うことで、それぞれどんな感じなのかみてみようと思います。

登録されているDID method

そもそも現在どんなDID methodが存在しているのか、という話になるのですが、DID methodはW3Cのコミュニティグループで「ゆるく」管理?されています。

https://w3c-ccg.github.io/did-method-registry/

今日(2020/07/23)の段階で59個も登録されてるんですね。残念ながらuPortはdeprecatedになってます(単にethrに引っ越しただけですが)。

Universal Resolverの状況

Universal ResolverではメソッドをサポートするためにDriverという単位でプラグインを追加していく形になります。

githubのレポジトリを見るとDriverの開発の方法や現在開発されているDriverの一覧を確認することが出来ます。

https://github.com/decentralized-identity/universal-resolver/

同じく今日時点で28種類ある様です。

使い方としては非常にシンプルでUniversal Resolverをデプロイし、エンドポイントに対して
curl -X GET http://localhost:8080/1.0/identifiers/did:sov:WRfXPg8dantKVubE3HX8pw
という感じでGETしてあげればDID metadataが返ってくるという仕掛けです。

これをWebで簡単に触れる様にしたのが先に書いた

https://uniresolver.io/

ってことです。


Microsoftの実装は?

前回のポストでも紹介しましたがMicrosoftもDIDの世界に突き進んでいるわけですが、当然マネージドなリゾルバを提供しています。
公開されているサンプルソースを掘っていくと、

https://beta.discover.did.microsoft.com/

というURLが出てきます。

ご存知の通りMicrosoftのDID/IONのメソッドは ion で、現在Universal Resolverではサポートされていません。ionメソッドのDIDをUniversal Resolverで解決しようとしてもNFです。



と言うことでMicrosoftのDIDを解決するには上記のリゾルバを使うしかなさそうです。

使い方としては、Universal Resolverと同じで


curl -X GET https://beta.discover.did.microsoft.com/1.0/identifiers/did:ion:EiBo3GQwMgF...
と言う感じです。

DID metadataの視認性を上げるためにFirefoxで開いてみます。


ふとした疑問として、どこまでMicrosoftのリゾルバは他のメソッドをサポートしているんだろう?と思って実験してみました。サンプルとして使ったDIDはUniversal Resolverのレポジトリにあるテスト用のものを使いました。

以下が結果です。
method support
sov OK
btctr OK
v1:test OK
key OK
ipid NG? Universal ResolverでもTimeoutするのでipid側の不具合かも
web NG? サンプルになっているのがdid:web:uport.meなのでDIDの問題かと
ethr NG. Timeout
nacl OK
jolo NG. Timeout
stack OK
erc725 NG? Universal ResolverでもExceptionが出るのでドライバの問題っぽい
hcr OK
neoid NG? Universal ResolverでもExceptionが出るのでドライバの問題っぽい
elem NG
github NG
ccp OK
work OK
ont OK
kilt OK
evan OK
echo OK
factom OK
dock OK
abt OK
trustbloc NG
sirius NG? Universal ResolverでもExceptionが出るのでドライバの問題っぽい
mpg NG? Universal ResolverでもExceptionが出るのでドライバの問題っぽい
trust NG? Universal ResolverでもExceptionが出るのでドライバの問題っぽい
io NG? Universal ResolverでもExceptionが出るのでドライバの問題っぽい



ということで完全に自分メモでした。





2020年6月9日火曜日

分散型ID「ION」のプレビューがアップデート

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

本ブログでも何度か触れたことのある分散型ID(この日本語訳は微妙だな、、、とは思いますが。Decentralized Identity)ですが、マイクロソフトも「ION(アイオン)」というコードネームで取り組んでいる、という話は過去のde:codeなどでも紹介してきました。

de:code 2019での発表資料


本ブログの過去ポスト
https://idmlab.eidentity.jp/2019/04/blog-post.html


先日のBuildでも当然セッションがあり、6月にUpdateあるよ!的な話がささやかれていたのですが、予定通り出てきました。

URLは相変わらずプレビュー間満載ですが・・・・
https://didproject.azurewebsites.net/docs/overview.html

新プレビューの概要

今回のプレビューで出来るようになったことは大きくは以下の通りです。

  • Azure ADとの統合(Credentialsのソースとして利用)
  • Microsoft AuthenticatorをWalletとして利用
  • Azure Key VaultでVerifiable Credentialsへの署名する鍵を管理
想像するにこんな感じの構造になっていると思われます。

構造としてはこんな感じです。
【Verifiable Credentialsの発行時】
  • Portable Identity Cards(実体のアプリ名はVerifiable Credentials Issuer Service)がAzure ADにEnterprise Applicationとして登録されている
  • Portable Identity CardsがAzure AD上に登録されたユーザの情報を元にVerifiable Credentials(VC)を発行する
  • ユーザはMicrosoft Authenticator(現状はAndroid/Beta版のみ対応)に発行されたVCをカードのメタファとして保存(ちなみに使われていると思われるAndroid用のSDKもここに公開されているので自作するのも可能なはず)
  • VCへの署名をするための秘密鍵はAzure KeyVaultで管理される
  • 分散台帳(ION)とのやり取りはPortable Identity Cardsサービスが使っているverifiablecredentials-verification-sdk-typescriptがやっている
【Verifiable Credentialsの利用時】
  • Portable Identity Cardsサービスと同じく、verifiablecredentials-verification-sdk-typescriptを使ったサービスへアクセス
  • サービスはQRコードを使ってVCの開示要求、ユーザはMicrosoft AuthenticatorでQEコードを読み込み、VCを送付
  • Portable Identity CardsサービスはVCをDLT上の公開鍵を使って検証(この辺もverifiablecredentials-verification-sdk-typescriptがやっている)


上記よりわかる通り、実体は「verifiablecredentials-verification-sdk-typescript」です。これをVC発行者がわかりやすいようにAzure AD/Azure KeyVaultと統合したものがPortable Identity Cardsであり、ユーザが使いやすいようにしたのがMicrosoft Authenticatorということです。



動きを見てみる

では、早速試してみましょう。

と言いたいところなのですが、Limited PreviewなのでMicrosoftに承認されないと動きません。(申請してみたけど返事がない・・・)
ただ、手順を見ているとAzure ADのEnterprise ApplicationsにVerifiable Credentials Issuer Serviceが出てきてObjectIDが取れればPreview機能が有効になっているよ、とあるのですが、一向にPortable Identity Cardsの管理コンソールがAzure Portalに現れません・・・・

上の図の通り、Previewが有効化されたテナントでAzure AD P1もしくはP2を有効にするとエンタープライズアプリケーションの一覧にVerifiable Credentials Issuer Serviceは出てきましたが、Portable Identity Cardsのコンソールが出てこない・・・(以下の図は手順書より)




ということで、自前のAzure ADを使うのはあきらめて素のverifiablecredentials-verification-sdk-typescriptを使ったサンプルコードを使って試してみます。
ちなみに、昨日までVCの発行まではうまく動いたのですが、検証はうまく動きませんでした。しかし、今朝サンプルコードが更新され現在はちゃんと検証まで動くようになりました。

サンプルコートはココにありますので、ローカルにcloneして使いました。

ちなみにMicrosoft Authenticatorからサービスにアクセスできる必要があるので、ngrokを使って外部からアクセスできるようにしました。

改造したコードはこちらです。
Issuer
Verifier

それぞれnpm installしてnode app.jsで実行できます。


まずはIssuerから動かします。
(前もってMicrosoft Authenticatorのベータ版を入れておいてください。現状Android版のみです)

起動すると画面上にボタンがあるのでクリックするとQRコードが表示されますので、これをAuthenticatorで読み込むと、Azure AD B2Cでのログインを要求されますので、アカウントの作成~ログインを行うとカード(Verified Credential Ninja)が追加されます。

Authenticatorでその他のアカウントを追加してQRコードを読み取る

Sign in to your accountでAzure AD B2Cへログインする。(初回は新規作成)

ログインが終わったらAcceptをタップします。

上手くいくとカードがAuthenticatorの中に保存されます。この中にVerifiable Credentialsとして氏名の情報が入っています。

次はVerifyです。
ngrokを使っていると2つ同時にサービスを挙げられないのでIssuerを停止しておきます。
Verifierを起動するとIssuerと同じようにボタンがあるのでクリックするとQRコードが表示されます。
これをAuthenticatorのカードの画面にあるQRコードリーダーを使って読み取ります。


上手くいくと画面上に「Congratulations, XX XX is a Verified Credential Ninja!」と出てきます。


ここまでは外から観測できたことなので、今後は引き続き中身を掘ってみようと思います。
IdentityCardRules.jsonファイルをいじくると他のOpenID Providerからでもクレデンシャル発行が出来るようですし。



参考)Buildのセッションの動画


2020年5月20日水曜日

Build速報!FacebookでAzure ADへログインする

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

Buildですね。リモート開催になって日本からでも参加しやすくなって睡眠時間が削られる日々をお過ごしだと思います。

今回も色々とAzure ADに関する新機能の発表がありました。

詳しくはAlexのBlogを参照してもらえれば良いのですが、今回はAzure AD B2Bの直接フェデレーションへのFacebookログインの登場(Public Preview)の話です。

AlexのBlog)
https://techcommunity.microsoft.com/t5/azure-active-directory-identity/build-2020-fostering-a-secure-and-trustworthy-app-ecosystem-for/ba-p/1257360

Azure AD B2Bの直接フェデレーションについてはこれまでも取り上げてきましたが、Googleに対応してから約2年、ここに来てFacebookに対応しました。

Googleとの連携の件
https://idmlab.eidentity.jp/2018/08/azure-ad-b2bgoogleid.html

カスタムドメイン vs 直接フェデレーションの件
https://idmlab.eidentity.jp/2020/05/azure-adbyoid.html



もはやB2Bとは?というしかない状態なのですが、早速触ってみましょう。

外部アイデンティティプロバイダの設定

これまでも紹介したことのある画面です。Azure ADのポータルを開き、External Identitiesメニューから「すべてのIDプロバイダー」を開くと「Google」に加えて新たに「Facebook」が選べるようになっています。


ここでFacebookを追加して、AppIdとAppSecretを追加すれば基本は終わりなのですが、設定前に外部ユーザによるサインアップを許可しておく必要があります。
「外部コラボレーションの設定」メニューを見ると、新しく「ユーザーフローによるゲストセルフサービスサインアップを有効にする」という設定が追加されているので有効にしておきましょう。

後はFacebook Developerコンソールで作成したアプリケーションのAppIdとAppSecretを設定すれば終わりです。

Facebook側の設定方法はAzure AD B2Cのドキュメントに記載がありますので、1点を除いてこちらをそのまま使って大丈夫です。
https://docs.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-facebook

その1点とは、そうですredirect_uriです。
直接フェデレーションの場合にFacebookに設定するredirect_uriはどうなるのか?というと、
https://login.microsoftonline.com/te/{テナントID}/oauth2/authresp
となります。

ここまで設定を進めると、ユーザーフローからAzure ADにアクセスするためのアプリケーション「aad-extensions-app」が自動的に登録されます。


ちなみに、このアプリケーションを削除すると面倒なことになるので、消さないようにしてください。
万一消してしまったらAzure AD B2Cでのb2c-extension-appと同じように回復をしてください。
参考)B2Cでの回復手順
https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/extensions-app


ユーザーフローの登録

外部IDプロバイダの設定が終わったら、次はユーザーフローの登録です。
基本この辺りもAzure AD B2Cと同じです。


ユーザーフローの名称(ポリシー名となります)、利用するIDプロバイダ、連携する属性を設定していきます。
尚、属性は標準で用意されているもの以外に「カスタムのユーザー属性」メニューから自分で好きな属性を追加することもできます。

これでIDプロバイダとユーザーフローの登録はおしまいです。

アプリケーションの登録

次に、先ほど作成したユーザーフローを使ってサインアップやサインインを行う対象となるアプリケーションを登録します。
ポイントは、APIのアクセス許可で「User.Read」スコープに対して管理者による同意をしておくこと、です。現状のユーザーフローでのユーザ作成やログイン時にユーザ自身による同意が上手く取れない?のでこの設定は入れておく必要がありそうです。

ユーザーフローとアプリケーションの紐づけ

アプリケーションを作成したら、先に作成しておいたユーザーフローを使う様に構成をします。
先ほどのExternal Identitiesメニューに戻り、先ほど作成したユーザーフローを開きます。アプリケーションに関する設定項目がありますので、ここで作成したアプリケーションを指定します。

これで一通りの設定は終了です。

動作確認

では早速動かしてみます。

このアプリケーションにアクセスする為には、以下のパラメータをつけてAuthorizationエンドポイント(https://login.microsoftonline.com/{テナントID}/oauth2/authorize)へアクセスする必要があります。(通常のOpenID Connectのアプリケーションと同じです)

  • client_id={登録したアプリのClient Id}
  • response_type=id_token
  • scope=openid
  • nonce={生成したnonceの値。テストなら何でもOK}
  • redirect_uri={登録したアプリのredirect_url}

今回、アプリケーションとしてはhttps://jwt.msを使ったのでこんなURLになります。
https://login.microsoftonline.com/{テナントID}/oauth2/authorize?client_id={クライアントID}&response_type=id_token&scope=openid&nonce=hoge&redirect_uri=https:%2F%2Fjwt.ms

実行してみると、いつものサインイン画面になるので、まずはアカウントを作成します。

アカウントの作成画面に「Facebookアカウントでサインイン」というメニューが出来ています。
ここでFacebookアカウントでサインインすると、Azure ADへのアカウント登録を行う際に追加で登録するアカウントを入力する画面が出てきます。

続行するとアカウントがAzure AD上に登録されます。
アカウントタイプはゲスト、ソースはFacebookになっているのがわかります。


ちなみに登録後、サインインする場合はサインインオプションをクリックするとFacebookログインのメニューが出ていますので、そちらを使ってサインインします。


いかがでしょうか?
基本はAzure AD B2Cの機能の一部を通常のAzure ADの直接フェデレーション向けに開放しただけなので、Azure AD B2Cに慣れている方は直感的に理解できると思います。

しかし、冒頭にも書きましたが、こうなってくると「B2Bとは?」という疑問がやはり出てきますが大人しくしておきましょう。

おまけ

たまたまテストに使ったAzure ADにG-SuiteとのSSO設定があったので、SAMLの属性マッピングの調整をちょこっとして、GmailにAzure ADの直接フェデレーションを使ってFacebookアカウントでログインする、というくだらないものを作ってみたので動画を貼っておきます。

2020年5月16日土曜日

Azure ADを拡張してOpenID Connect for Identity Assuranceに対応させる

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

先日、OpenID ConnectのID保証に関する拡張仕様である「OpenID Connect for Identity Assurance」について紹介しましたが、実際に仕様を理解するためには実装してみるのが一番、ということでAzure Active Directoryを拡張して実装してみようと思います。(尚、現状は完成している訳ではありません。軽く動作を確認してみた程度です)

Azure ADに足りないもの

OpenID Connect for Identity Assuranceを実装する上で、Azure ADに足りないものは最低限でも以下の通りです。

  • Authorizationエンドポイントがclaimsパラメータを受け付ける機能
  • verified_claims等の属性をid_tokenやuserInfoエンドポイントから返す機能

逆に、Azure ADでも以下について当然ですが出来ます。

  • 認証
  • ユーザデータを保持するデータベース
  • アプリケーション(Client)管理

実装に向けた戦略

ということで、以下の戦略で拡張してみることにしました。
  • Azure ADのエンドポイントをラップするWebアプリを用意し、request/responseの整形を行う
  • 認証、データ保持、アプリケーション管理はAzure ADの機能を使う
  • OpenID Connect for Identity Assuranceで拡張された属性(verified_claims関係)はAzure ADのスキーマを拡張する
こんな感じの仕組みになるはずです。


いざ実装

準備1:Azure ADのスキーマを拡張する

Azure ADにはスキーマ拡張を行う機能がありますので、今回はこの機能を使ってAzure AD上にID保証に関する情報、ID保証済みの属性を保存できるようにします。

Azure ADのスキーマ拡張に関するドキュメントはこちら

OpenID Connect for Identity Assuranceでは「verified_claims」というエレメントの定義がされており、配下に「verification」と「claims」というエレメントが存在します。
  • verification : IDの検証をどのように行ったのか?の記録
    • trust_framework : どんなルールによってIDの確認・検証をしたのか。例えば犯罪収益移転防止法や携帯電話不正利用法などの、本人確認を行った際の根拠法やルールを指定します
    • Evidence : ID確認時に利用した証拠(エビデンス)を指定します。免許証などですね。
      • type : エビデンスの種類を指定します。id_document(証明書類)、utility_bill(公共料金の領収書)、qes(欧州限定ですがeIDASの電子証明書)がありますが、ここではid_documentを使いました。
      • method : typeで指定したエビデンスをどのように確認したのか?を指定します。例えば対面で確認した場合は「Physical In-Person Proofing」ということで「pipp」という値を設定します。
      • document : typeにid_documentを指定した場合に、具体的に何の証明書類を使ったのか?を指定します。例えば日本の免許証なら「jp_drivers_license」を指定します。
      • issuer : 証明書を発行した機関に関する情報を指定します。
        • name : 機関名
        • country : 機関の属する国
      • date_of_issuance : 証明書類の発行日を指定します。
      • date_of_expiry : 証明書の有効期限を指定します。
  • claims : 検証された属性(ここは要求された属性を普通に指定します)
    • given_name : 検証済みの名
    • family_name : 検証済みの姓
    • など

この形でAzure ADの属性を拡張出来ればいいのですが、上記ドキュメントにもある通り、拡張できる属性の型はStringやInteger、DateTimeなどに限定され入れ子の構造や配列構造が取れません。本来なら複数のエビデンスを使ったID証明などもあり得ますが、現状はデータをフラットで持つしかありませんので諦めます。

具体的な方法は以下の通りです。
  • Directory.AccessAsUser.Allをスコープに指定してaccess_tokenを取得する
  • https://graph.microsoft.com/v1.0/schemaExtensionsに拡張したいスキーマの構造(JSON)をPOSTする
  • 成功したら他のクライアントからでも参照可能な様にスキーマをアクティベーションする(status属性をPATCHでActiveに更新する)
今回、以下の2つの拡張属性を作りました。
  • verification
  • verifiedClaims

それぞれのPOSTしたデータはこちらです。
- verification
{
    "id":"verification",
    "description": "verification extension for OpenID Connect for Identity Assurance",
    "targetTypes": [
        "User"
    ],
    "properties": [
        {
            "name": "verificationId",
            "type": "String"
        },
        {
            "name": "trustframework",
            "type": "String"
        },
        {
            "name": "evidenceType",
            "type": "String"
        },
        {
            "name": "evidenceMethod",
            "type": "String"
        },
        {
            "name": "evidenceDocumentType",
            "type": "String"
        },
        {
            "name": "evidenceDocumentIssuerName",
            "type": "String"
        },
        {
            "name": "evidenceDocumentIssuerCountry",
            "type": "String"
        },
        {
            "name": "evidenceNumber",
            "type": "String"
        },
        {
            "name": "evidenceDateOfIssurance",
            "type": "DateTime"
        },
        {
            "name": "evidenceDateOfExpiry",
            "type": "DateTime"
        }
    ]
}



- verifiedClaims
{
    "id": "verifiedClaims",
    "description": "verified claims extension for OpenID Connect for Identity Assurance",
    "targetTypes": [
        "User"
    ],
    "properties": [
        {
            "name": "verificationId",
            "type": "String"
        },
        {
            "name": "givenName",
            "type": "String"
        },
        {
            "name": "familyName",
            "type": "String"
        }
    ]
}


ちなみに、拡張スキーマの単位でid(属性名となります)をつけることが出来ますが、.net、.comなど限られたTLDでカスタムドメインをAzure ADに追加している場合は、[カスタムドメイン名]_[拡張属性名]という名前で属性を作ることが出来ますが、カスタムドメインを持っていない場合は「ext][8桁のランダム文字列]_[拡張属性名]という形で属性名が払い出されます。

当然ですが、この拡張属性に値を入れた状態のユーザを用意しておく必要があります。この辺りはGraph APIを使って値のセットをしてください。

準備2:Azure ADをラップするWebサービスを作る

ココが本番です。といってもやることはシンプルです。
(本来はちゃんと実装しないと危険ですので注意してください。本ポストにサンプルコードが出てきますが、かなり手抜きなのであくまで参考として捉えてください


  • Authorizationエンドポイント
    • clientからの要求の中でAzure ADが受け取ってくれないclaimsパラメータをパースして保持します。後からレスポンスを作るときに何が要求されていたのかを判断するために使います。
    • ※テスト実装では決めうち実装なので実際には保持していません
router.get('/authorize', (req, res) => {
    // get claims from request
    var _claims = req.query.claims;
    // redirect to Azure AD
    var target = lib.addQueryTo(conf.AAD_AuthZ, {
            response_type: 'code',
            scope: 'openid User.Read',
            client_id: req.query.client_id,
            state: req.query.state,
            redirect_uri: req.query.redirect_uri });
    res.redirect(target);
});


  • Tokenエンドポイント
    • codeを受け取ってAzure ADのTokenエンドポイントへ渡してaccess_token、id_tokenを受け取ります。
    • id_tokenには当然verified_claimsが含まれていないので、一度id_tokenをほどき、必要に応じてaccess_tokenを使ってMicrosoft Graphで追加の属性を取得、id_tokenを生成してclientへ返却します。
    • ※テスト実装ではPKCEに対応させていませんので、code横取りをして実装しています。本来はclientとPKCEに使う情報を共有しないと横取り出来ないので、ここはちゃんと考えないとダメです。
router.post('/token', async (req,res) => {
    try{
        let response_from_aad_token = await request({
            url: conf.AAD_Token,
            method: "POST",
            form: {
                grant_type: 'authorization_code',
                code: req.body.code,
                client_id: req.body.client_id,
                client_secret: req.body.client_secret,
                redirect_uri: req.body.redirect_uri
            },
            json: true
        })
        console.log(response_from_aad_token);
        // extract response and re-generate id_token with verified claims
        let decoded_jwt = jwt.decode(response_from_aad_token.id_token)

        // get additional claims using graph api
        let response_from_graph = await request({
            url: conf.AAD_Graph + "/v1.0/me?$select=id,userPrincipalName," + conf.AAD_ExtPrefix + "_verifiedClaims," + conf.AAD_ExtPrefix + "_verification",
            method: "GET",
            headers: {
                'Authorization': 'Bearer ' + response_from_aad_token.access_token,
                'Content-Type': 'application/json'
            }
        })
        console.log(response_from_graph);
        var user = JSON.parse(response_from_graph);
        // get properties from user object
        for (var prop in user){
            if(prop.includes('_verification')){
              var _verification = {
                trustframework: user[prop].trustframework,
                evidenceType: user[prop].evidenceType,
                evidenceMethod: user[prop].evidenceMethod,
                evidenceDocumentType: user[prop].evidenceDocumentType,
                evidenceDocumentIssuerName: user[prop].evidenceDocumentIssuerName,
                evidenceDocumentIssuerCountry: user[prop].evidenceDocumentIssuerCountry,
                evidenceDateOfIssurance: user[prop].evidenceDateOfIssurance,
                evidenceDateOfExpiry: user[prop].evidenceDateOfExpiry
              }
            } else if(prop.includes('_verifiedClaims')){
              var _verifiedClaims = {
                familyName: user[prop].familyName,
                givenName: user[prop].givenName
              }
            }
        }
        // create new jwt.
        var privateKey = fs.readFileSync('./private_key.pem', 'utf-8')
        var new_jwt = null;
        if (typeof _verification !== 'undefined') {
            new_jwt = jwt.sign({
                sub: decoded_jwt.sub,
                iss: 'https://' + req.headers.host,
                aud: decoded_jwt.aud,
                iat: decoded_jwt.iat,
                exp: decoded_jwt.exp,
                email: decoded_jwt.email,
                verified_claims: {
                    verification: {
                        trust_framework: _verification.trustframework,
                        evidence: [
                            {
                                type: _verification.evidenceType,
                                method: _verification.evidenceMethod,
                                document: {
 type: _verification.evidenceDocumentType,
 issuer: {
name: _verification.evidenceDocumentIssuerName,
country: _verification.evidenceDocumentIssuerCountry
 },
 number: _verification.evidenceNumber,
 date_of_issuance: _verification.evidenceDateOfIssurance,
 date_of_expiry: _verification.evidenceDateOfExpiry
                                }
                            }
                        ]
                    },
                    claims: {
                        given_name: _verifiedClaims.givenName,
                        first_name: _verifiedClaims.familyName
                    }
                }
            }, privateKey, { algorithm: 'RS256' });    
        } else {
            new_jwt = jwt.sign({
                sub: decoded_jwt.sub,
                iss: 'https://' + req.headers.host,
                aud: decoded_jwt.aud,
                iat: decoded_jwt.iat,
                exp: decoded_jwt.exp,
                email: decoded_jwt.email,
            }, privateKey, { algorithm: 'RS256' });    
        }
        
        res.send({
            token_type: "bearer",
            scope: "openid",
            expires_in: response_from_aad_token.expires_in,
            access_token: response_from_aad_token.access_token,
            id_token: new_jwt
        });
    } catch(e){
        console.log(e);
    }
});


  • userInfoエンドポイント
    • access_tokenを使ってMicrosoft Graphから必要な属性を取得して、整形した上でclientへ返却します
    • ※テスト実装ではここは実装していません。id_tokenにverified_claimsを入れて返却するところまでです。
  • その他
    • .well-known/openid-configurationとかjwks_uriは必要に応じて実装します。id_tokenの署名をAzure ADではなくこのWebサービス側で行うので対応した公開鍵などの情報をclientへ公開してあげる必要があります。

とりあえずこんな感じでnode.jsで実装してみています。


実際に動かす

テストするにしてもclientが必要になるので、phpでちょこっと書いておく必要があります。
やるべきことはclaimsパラメータを認証要求に乗せて検証済み属性を要求する、ということだけであとは普通のOpenID Connectのクライアントです。

こんな感じですね。
    // claims生成
    $verificationArray = array(
        'trust_framework'=>'null'
    );
    $claimsArray = array(
        'given_name'=>'null',
        'family_name'=>'null'
    );
    $verified_claimsArray = array(
        'verification'=>$verificationArray,
        'claims'=>$claimsArray
    );
    $id_tokenArray = array(
        'email'=>'null',
        'verified_claims'=>$verified_claimsArray
    );
    $claimsArray = array(
        'id_token'=>$id_tokenArray
    );
    
    // GETパラメータ関係
    $query = http_build_query(array(
        'client_id'=>$client_id,
        'response_type'=>$response_type,
        'redirect_uri'=> $redirect_uri,
        'scope'=>'openid User.Read',
        'state'=>$state,
        'nonce'=>$nonce,
        'claims'=>json_encode($claimsArray)
    ));
    // リクエスト
    header('Location: ' . $authorization_endpoint . '?' . $query );


動かすとこんな感じになります。
node.jsを動かすのにglitchを使っているので起き上がるまでにちょっと時間がかかってますが。。。


ということで、ここまでのソースはこちらにあります。
くれぐれも真似して使わない様にしてください。色々危ないので。
https://github.com/fujie/aad_oidc4ida

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ログインには使えない




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



2020年4月29日水曜日

eKYCとOpenID Connectに関する最近のアクティビティ

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

年明けから異常な忙しさでほぼ4か月ぶりの投稿になってしまいました。

今日はOpenID Foundationが今年から本格的に仕様化を進めているeKYC、ID保証に関する新しい仕様である「OpenID Connect for Identity Assurance」について紹介したいと思います。
ワーキンググループが始まったころは、ここまでリモートワークや非対面が重要になる、という局面を誰も予測していませんでしたが、ここに来てオンラインでのID保証、eKYCに関するニーズが本格化しているのは恐ろしい偶然としか言いようがありません。

尚、この「OpenID Connect for Identity Assurance」は、ちょうど1年程前から私もOpenIDファウンデーションジャパンのKYCワーキンググループをリードさせていただいている関係で共同議長を務めさせていただいている、米国OpenID FoundationのeKYC and Identity Assurance Working Groupで仕様策定が進められています。

ID保証(Identity Assurance)とは?

アイデンティティ管理に必ず付いて回るのが、デジタル・アイデンティティの精度や鮮度をはじめとする「信頼性」の課題です。

例えば、エンタープライズのシナリオでは、そのアカウントの持ち主はまだ在籍しているのか、権限付与に使っている役職は正確なのか?などといった「アイデンティティ・ライフサイクル」を管理するためにMicrosoft Identity ManagerやLDAP Managerなどの製品を使って効率的かつ正確なアイデンティティ管理を行います。

また、コンシューマのシナリオではいわゆる「KYC:Know Your Customer」といわれるID保証に関する課題を常に抱えています。これは例えば、サービスの利用を開始する際に登録する氏名や住所、年齢などの属性が本当に正しいのか?という「本人確認」や「身元確認」と言われる課題で、サービスの種類によっては利用者が一定の年齢を超えていることが法令で決められていたり、サービスの利用を許可するために必要な収入や本人到達性などの要件を満たす必要があったりするケースにおいては非常に重要なID保証のユースケースの一つです。例えば、金融機関におけるAML(Anti Money Laundering:マネーロンダリング防止)やオンラインゲーム等における年齢制限などがユースケースとして該当しますね。


ちなみにIDに関する保証レベルを綺麗に体系化しているのが「NIST(米国国立標準技術研究所)」が発行しているセキュリティに関するガイドラインシリーズ(SP/Special Publications)の800-63です。※通称NIST SP800-63
尚、NIST SP800-63は連邦政府内の情報保護の要件を規定している「NIST SP800-53」の中のデジタル・アイデンティティに関するガイドラインとして位置付けられていますが、連邦政府と取引をする民間企業を対象としてNIST SP800-53から抜き出す形で定義された「NIST SP800-171」にも同様に適用されることなどから、実質的にデジタル・アイデンティティの保証に関するデファクトスタンダードとなっています。

脱線を続けますが、NIST SP800-63では以下の3つの区分でID保証に関する規定をしています。

  • Identity Assurance Level(IAL):NIST SP800-63A
    • ID登録を行う時の本人確認・身元確認の強度(自己申告<非対面<対面など)
  • Authenticator Assurance Level(AAL):NIST SP800-63B
    • 認証器の強度(単要素<ソフトウェアベースの多要素<ハードウェアベース多要素など)
  • Federation Assurance Level(FAL):NIST SP800-63C
    • アサーション保護の強度(Bearer+署名<Bearer+署名+暗号化<HoK+署名+暗号化など)

各ガイドラインの日本語訳をOpenIDファウンデーション・ジャパンが公開しているので、興味のある方は参考にしてください。
https://openid-foundation-japan.github.io/800-63-3-final/index.ja.html


このように単にアイデンティティに関する「保証」といっても多岐にわたって考慮すべき点があります。


OpenIDファウンデーションジャパンにおける活動

冒頭で述べた通り、OpenIDファウンデーションジャパンにおいても先に述べた「KYC」に関するワーキンググループを2019年1月より設置し活動をしています。

このワーキンググループではOpenID Connectの仕様の拡張などといった単純に技術にフォーカスしたワーキングではなく、日本国内の各種業界(金融、テレコム、古物など)におけるID保証、本人確認に関する現状の調査、および現在業界毎に分断されている本人確認に関する要件の共通化に向けた課題の洗い出しなどポリシー面からの整理や、OpenID Connect for Identity Assuranceの仕様への国内事情のインプット、分散台帳を活用したアイデンティティの保証として注目されている「DID:Decentralized Identifier」や「VC:Verifiable Credentials」といった新しい技術の調査も、NFCリーダを使った公的証明書のICチップ読み取りや画像認識などeKYCに関連する技術に関しても網羅的に調査を行っています。

現在、ワーキンググループは第1シーズンの活動を終え、第2シーズンの活動を開始したところですので、興味のある方はこの機会にOpenIDファウンデーションジャパンへの入会とワーキンググループへの参画をご検討ください。

尚、第1シーズンの活動実績と成果物については2020年1月に開催された「OpenID Summit Tokyo」の中で発表させていただきましたので、詳しくは発表資料・成果物をご覧ください。



米OpenID Foundationにおける活動

ようやくOpenID Connectの仕様の話です。米OpenID Foundationでは2020年1月より「eKYC and Identity Assurance Working Group」という新しいワーキンググループを立ち上げ、ID保証に関するOpenID Connectの新しい仕様である「OpenID Connect for Identity Assurance(通称OIDC4IDA)」の策定を進めています。尚、先に述べた通り、OpenIDファウンデーションジャパンでKYCワーキンググループをリードさせていただいている縁もあり、こちらのワーキンググループでは議長であるDr. Torste Lodderstedtの元、Mark Haine, Anthony Nadalinと共に共同議長を務めさせていただいております。

どのような仕様か

Abstractに記載されているとおり、本仕様は「OpenID Providerがエンドユーザに関する検証済みの属性をRelying Partyに対して提供するためのOpenID Connectの拡張」であり、「特定の法律に基づき自然人のアイデンティティを検証するために利用されることを意図して」定義されています。
This specification defines an extension of OpenID Connect for providing Relying Parties with verified Claims about End-Users. This extension is intended to be used to verify the identity of a natural person in compliance with a certain law.

簡単に言うと、OpenID Providerに登録されているアイデンティティが何に基づき、どのように検証されたものか?というメタデータを含めてRelying Partyに対して提供することにより、アプリケーション側が安心してサービスを提供することが出来るようにすることを目指しています。

例えば、ial_exmample_goldというトラストフレームワークに則って確認済みのgiven_nameとfamily_name属性の値である、ということをRelying Partyに伝達する時、id_tokenやuserInfoエンドポイントから以下のような形でverified_claimsとしてJSONが返却されます。
{
   "verified_claims":{
      "verification":{
         "trust_framework":"ial_example_gold"
      },
      "claims":{
         "given_name":"Max",
         "family_name":"Meier"
      }
   }
}

細かい技術面での解説はAuthleteの川崎さんが解説してくれていますし、少し前のDraftですが仕様の日本語化もされていますので、そちらをご覧いただければと思います。



仕様の現状

現在、本仕様は2nd Implementer's draftのレビュー期間が終わり、仕様の承認に関する投票が開始されています。
https://openid.net/2020/04/27/notice-of-vote-for-second-implementers-draft-of-openid-connect-for-identity-assurance-specification/

こちらも興味があれば米国OpenID Foundationの会員(個人でもなれます)として加入していただき、仕様策定にコントリビュートしていただければと思います。
(意外と日本人もいますよ!)




2019年12月31日火曜日

年忘れはFIDOで!指紋認証付きのeWBM Goldengateを試す

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

世の中は大晦日ですが、今日になってeWBMさんよりGoldengate G310が届いたので軽く試してみます。

届いたのは、G310というFIDO2対応のキーです。
https://www.ewbm.com/security-keys/goldengate-g310/



韓国から直送で送られてきたっぽいです。
まだ日本のAmazonでは買えないので、直販サイトか米国Amazonで買うのがいいみたいです。
 直販サイト
  https://www.ewbm.com/store/products/goldengate-g310/
 米国Amazon
  https://www.amazon.com/s?k=ewbm+g310&ref=nb_sb_noss_2

定価は60ドルですが、直販サイトだと初回は45ドルで買えるみたいです。
(私はMVPのサードパーティ特典で頂きました)


なんだかキーばっかり増えちゃって微妙な感じですが、Yubikeyとの大きな違いは指紋認証機能があることですね。
キーだらけ・・・


やれることは正直他のFIDO2対応のキーと変わらないので、今更動きについて解説する必要もないと思いますので、先日のAXIES(大学ICT推進協議会)の年次大会でお見せしたG SuiteへAzure AD B2C+FIDO実装を使ってパスワードレスでログインするデモを張っておきます。



最大の特徴の指紋登録ですが、以下の2通りの方法で設定できます。
1.公式のツール「Goldengate BioManager」を使う
2.Windowsのアカウント設定を使う

それぞれ簡単に。
まずは公式ツール「Goldengate BioManager」を使う方式から。

ツールはこの辺りからダウンロードできます。
 https://www.ewbm.com/support/BioManager/

ちなみにダウンロードしてセットアップしようとするとWindowsに実行をブロックされますが無視して進めます・・・

セットアップが終わりツールを起動するとこんな画面が出てきます。
言語の切り替えもできて、日本語も選べます。


次は指紋の登録です。

指紋追加を選ぶとタッチする様に促されるのでベタベタ触ります。


登録が終わると、登録済みの指紋以外でタッチしてもキーが反応しなくなります。
あと、PINが聞かれなくなります。
※指紋登録していない状態だと単純にタッチ+PINだけでサインインできる(Yubikeyと同じ挙動)が、指紋登録をすると登録していない指だとサインインできない。


ちなみに、2つ目の登録手段であるWindowsの標準の設定です。
設定⇒アカウントのセットアップから登録できます。

ちなみにWindows Helloの設定も同じ設定メニュー内にありますが、あくまでセキュリティキーの設定なのでここでセットアップしてもセキュリティキーでWindowsログインが出来るようになるわけではありません。もしOSログインにも使いたければ使うアカウントの設定をMicrosoftアカウントなりAzure ADアカウントなりで設定する必要があります。

指紋の追加は先ほどのBioManagerとほぼ同じです。




セキュリティキー+PINだけでは不安な方は指紋認証機能も付いているGoldengateも一つの選択肢となりえますね!