2015年8月13日木曜日

[Azure AD]OpenID ConnectのUserInfoエンドポイントを使ってユーザ情報を取得する

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

今回はAzure Active Directory(Azure AD)からOpenID Connectを使ってユーザの属性情報を取得してみます。

先日のポストではASP.NETアプリケーションから属性を取得する方法として、id_tokenの中身をデコードする方法とGraph APIを使って問い合わせる方法を紹介しましたが、今回はOpenID ConnectのUserInfoエンドポイントから情報を取得します。


◆技術仕様

OpenID Connect1.0の仕様を見ると、UserInfoエンドポイントは以下のように定義されています。

UserInfo Endpoint は, 認証された End-User に関する Claim を返す OAuth 2.0 Protected Resource である. 要求された End-User のクレームを取得するため, クライアントは OpenID Connect Authentication を通して得られた Access Token を用いて UserInfo Endpoint に要求する. これらのクレームは通常, クレームの名前と値のペアのコレクションを含んだ JSON オブジェクトで表現される.

参考)OpenID Connect Core 1.0 日本語訳

同じく、UserInfoエンドポイントへのアクセスの流れがImplementer's Guideに記載されています。


参考)OpenID Connect Basic Client Implementer's Guide 1.0 日本語訳

今回は、このガイドに従いAzure ADのUserInfoエンドポイントからユーザの属性情報を取得してみます。


◆Azure ADのエンドポイント情報の確認

UserInfoを取得するにあたって必要なAzure ADのエンドポイント情報を/.well-known/openid-configurationエンドポイントで確認します。
普通にブラウザでエンドポイントにアクセスすると各種構成情報がJSON形式で表示され、エンドポイントのアドレスについても以下の通り確認できます。

エンドポイントアドレス
Authorizehttps://login.microsoftonline.com/common/oauth2/authorize
Tokenhttps://login.microsoftonline.com/common/oauth2/token
UserInfohttps://login.microsoftonline.com/common/openid/userinfo


参考)openid-configurationエンドポイント



◆Azure AD上にクライアント登録をする

OAuth2.0のリソースアクセスなので、当然クライアントを事前に登録しておく必要があります。Azure ADにおけるクライアント登録はディレクトリ設定の中のアプリケーションのメニューから行います。
アプリケーションはWebアプリケーションとして登録し、URLの返信(redirect_uri)およびクライアントID(client_id)、キー(client_secret)を取得しておきます。
今回はテスト用なのでredirect_uriは適当にhttp://localhostとかにしておき、あとはChrome ExtensionのAdvanced REST clientを使って動作確認をしています。






◆アクセスしてみる

さて、実際にアクセスしてみたいと思います。
流れとしては、先に紹介した仕様の通り、
1. Authorizationエンドポイントへアクセスしてcodeを取得する
2. TokenエンドポイントへcodeをPOSTしてaccess_tokenを取得する
3. 取得したaccess_tokenをAuthorizationヘッダにつけてUserInfoへアクセス、情報を取得する
という順に行います。


1. Authorizationエンドポイントへアクセスしてcodeを取得する

ブラウザを使って以下のGETリクエストを発行します。(改行は取り除いてください)

https://login.microsoftonline.com/common/oauth2/authorize?
    client_id=0856fxxxxxxxxxxx6bd0cf&
    response_type=code&
    redirect_uri=http%3A%2F%2Flocalhost&
    scope=openid&
    state=12345


すると、redirect_uriに指定したアドレスにクエリパラメータとしてcodeがついてきますので、値をコピーしておきます。

http://localhost/?
    code=AAABAAAAixxxxlWqrLsxILSH6fJ99WvmIAA&
    state=12345&
    session_state=9fac9xxxxx

尚、codeの有効期限は非常に短いのでこの後の作業は手早く行う必要があります。


2. TokenエンドポイントへcodeをPOSTしてaccess_tokenを取得する

ここからはAdvanced REST clientを使います。
先ほど取得したcodeおよびclient_id、client_secret、redirect_uriと合わせてgrant_typeにauthorization_codeを指定して、TokenエンドポイントへPOSTします。

https://login.microsoftonline.com/common/oauth2/token
    grant_type: authorization_code
    client_id:  0856fxxxxxxxxxxx6bd0cf
    code: AAABAAAAixxxxlWqrLsxILSH6fJ99WvmIAA
    redirect_uri: http://localhost
    client_secret: WjFotGxxxxxxxxx+imo=


すると、以下の様にaccess_token、refresh_token、id_tokenが返ってきます。

{
expires_in: "3600"
token_type: "Bearer"
expires_on: "1439454521"
access_token: "AAABAAAAixxxxxxxxWC0VQSAA"
refresh_token: "AAABAAAAxxxxxxxx6XIAA"
id_token: "eyJ0eXAiOiJKVxxxxxxxxEqegYSCaCaQrw"
}


もちろん以前紹介したようにid_tokenをデコードすればユーザの属性情報は取得できますが、あえてスルーします。

参考)id_tokenをデコードした結果
{
  "aud": "0856fxxxxxxxxxxx6bd0cf",
  "iss": "https://sts.windows.net/2c.......fff/",
  "iat": 1439450621,
  "nbf": 1439450621,
  "exp": 1439454521,
  "ver": "1.0",
  "tid": "2c.........fff",
  "oid": "785........4bed4",
  "upn": "jbecker@example.net",
  "sub": "NnF_CZAQ...............qoOv4",
  "given_name": "Jason",
  "family_name": "Becker",
  "name": "Jason Becker",
  "amr": [
    "pwd"
  ],
  "unique_name": "jbecker@example.net",
  "onprem_sid": "S-1-5-21-.........2-1618"
}



3. 取得したaccess_tokenをAuthorizationヘッダにつけてUserInfoへアクセスする

いよいよUserInfoエンドポイントへアクセスします。
前のステップで取得したaccess_tokenをAuthorizationヘッダにつけてGETリクエストを出せば良いので、同じくAdvanced REST clientでクエリを発行します。

https://login.microsoftonline.com/common/openid/userinfo
    Authorization: Bearer AAABAAAAixxxxxxxxWC0VQSAA

結果、以下とおりJSONでユーザの属性情報が取得できます。

{
tid: "2c.........fff"
oid: "785........4bed4"
upn: "jbecker@example.net"
sub: "NnF_CZAQ...............qoOv4"
given_name: "Jason"
family_name: "Becker"
name: "Jason Becker"
}


id_tokenの方が情報が多いですね・・・。

ちなみに、現状Azure ADでは一般的なOpenID ConnectのProviderの様にprofileやemailなどのscopeが使えず、openidのみしか指定できないので、取得するclaim(属性)を指定することは出来ません。


尚、本日アナウンスされたApp Model v2.0用のAPIバージョン(oauth2/v2.0/のエンドポイント)ではUserInfoへのアクセスがまだ使えないので、マイクロソフトアカウントに関する属性情報の取得はできません。

0 件のコメント: