Windows 10 との SSO 開発 (Web Account Manager を使用したNative Application)


開発者にとっての Microsoft Azure Active Directory

こんにちは。

//build/, Ignite 関連のトピックを続けます。今週は、Azure AD です。

 

Windows 10 と Azure AD Join

既に Windows 8 の頃から Microsoft Account (Cloud 上のアカウント) を使った OS のログインが可能でしたが、Windows 10 では Azure Active Directory への参加 (Azure AD Join) が可能です。(Device 自身を参加させるという概念です。)

また、Windows 10 では、Microsoft Passport (旧 Next Generation Credential) という新しいビルトイン サービスを使って、人が理解できる軽微な文字列をネットワーク上に流すパスワードを使った方式に代わり (もちろん、これまでも SSL 暗号化など必要な対策はされていましたが)、ネットワーク上を流れない PIN や biometric 認証 (Windows Hello) を使って、TPM (つまり、ソフトウェア的に可搬ではなく、ハードウェアに依存した入れ物) に登録された private key を取り出し、IdP (Azure AD) との信頼関係を確立する、よりセキュアな方式を使うことができます。(この方式では、既定で、ソフトウェア的な PIN とハードウェア的な Device などの複数の要素が必要で、かつソフトウェア要素についてはネットワークからの Attack の危険などがありません。)
入力の手間を増やさずセキュリティを強化する新しい技術が使用されています。(以前紹介した 電話を使用した二要素認証 (多要素認証) と異なり、ユーザーはこれまでのパスワード入力とほぼ同じ操作、もしくはそれ以上の簡易な操作で目的を達成できます。)

こうした 高度化するオペレーティング システム (Windows) に対し、Native Application との間に SSO 体験 (すなわち、OS にログインしたら、その Credential を使ってそのまま他のサービスを利用できるユーザー体験) を実現する場合、上記のフローを意識した難解な処理が必要になりますが、ここで紹介する Web Account Manager (下図) を使用すると、こうした面倒な手続きをビルトインされたコンポーネント (Web Account Manager, Web Account Manager Provider) に任せて、プログラマーは Web Account Manager に対する簡単な操作のみでアプリケーションを構築できます。


Source : "//build/ 2015 Single Sign-On with Secure Authentication" (Karanbir Singh)

今回は、このプログラミングについて解説します。

補足 : Microsoft Passport では、Fast ID Online (FIDO) 認証に対応した他のサービスとの組み合わせが可能であり、かつ、上図の Web Account Manager Proviver 自体を Custom に提供できます。(上図の Microsoft Web Account Manager Provider は、Windows 10 にビルトインされた既定の Web Account Manager Provider です。)
ここでは、この開発方法 (Custom の Web Account Manager Provider の構築方法) については説明しません。(というか、やったことがないので、よくわかりません。。。)

 

事前準備 (Azure AD Join)

まず、Windows 10 で Azure AD Join (Azure Active Directory Join) をおこなうために、Azure Portal (Classic Portal) を開き、あらかじめ、下図の通り、Device の Azure AD Join を有効にしておきます。
そして、Windows 10 を Azure AD のテナントに参加 (Join) させます。

ここでは手順詳細は説明しませんが、 下記の AD Team Blog や 富士榮さんのブログ (IdM 実験室) が参考になります。

[Active Directory Team Blog] Azure AD Join on Windows 10 devices

http://blogs.technet.com/b/ad/archive/2015/05/28/azure-ad-join-on-windows-10-devices.aspx

 

Windows 10 との SSO 開発 (Web Account Manager API)

準備ができたら、Azure AD に Join した Windows 10 の Device (Machine) 上で、SSO をおこなうカスタム アプリケーションを構築してデバッグ実行してみます。
今回、C# を使用した Universal Windows アプリを作成してみます。

上述の Web Account Manager と連携する処理をプログラミングするには、Platform SDK に含まれる Web Account Manager API を使用します。
この API を使用するには、現時点では、Windows 10 と Visual Studio 2015 が必要です。(将来は .NET 版の ADAL などに包含される予定です。)

補足 : 上述の通り、Windows 10 に特化した方法になりますので、他の Client の場合には、従来通り ADAL などを使用して開発してください。

まず、通常の Azure AD の Application 登録同様、Azure AD のテナントに Native Client Application を追加します。(この際、作成される Client Id をコピーしておきます。)
Permission は、今回、下図の通り既定の設定をそのまま使用します。(この resource 名は https://graph.windows.net になります。)

Universal Windows App を Debug 実行でインストールするため、あらかじめ、Azure AD に Join した Client 開発環境で、Windows 10 の [設定] - [更新とセキュリティ] - [開発者向け] を選択して [開発者モード] を有効にします。

また、Visual Studio の [ユニバーサル Windows アプリ開発ツール] (特に、その中に含まれる Windows 10 SDK) を追加しておきます。

では、プログラムを作成しましょう。
Visual Studio 2015 を開き、Windows Universal App の Project を新規作成します。

今回は、Button を配置した簡単なアプリケーションを作成し、Button を押すと Web Account Manager API を使って、「https://graph.windows.net」(Microsoft Azure Active Directory Graph) の resource にアクセスするための Access Token を取得します。

Button を Click した際の処理として、下記の通り記述します。
これまで ADAL を使用したことがある方なら、プログラミング スタイルは、ほとんど変わらない点にお気づきでしょう。
上図の通り、Web Account Manager が特定の Web Account Manager Provider を呼び出すので、その点を意識した実装方法になります。

. . .
using Windows.Security.Authentication.Web.Core;
using Windows.UI.Popups;
. . .

private async void button_Click(object sender, RoutedEventArgs e)
{
  // get Microsoft Web Account Manager Provider
  var provider =
    await WebAuthenticationCoreManager.FindAccountProviderAsync(
      "https://login.microsoft.com",  // provider name
      "organizations");

  // request result token to Web Account Manager
  WebTokenRequest webTokenRequest = new WebTokenRequest(
    provider,
    "",
    "553bd5ae-0b5c-40b3-abeb-4ffa34eca2d3");
  webTokenRequest.Properties.Add(
    "resource", "https://graph.windows.net");
  WebTokenRequestResult webTokenResult =
    await WebAuthenticationCoreManager.RequestTokenAsync(
      webTokenRequest);

  // show access token
  if(webTokenResult.ResponseStatus == WebTokenRequestStatus.Success)
  {
    var dialog = new MessageDialog("Access Toke : "
      + webTokenResult.ResponseData[0].Token);
    await dialog.ShowAsync();
  }
  else
  {
    var dialog = new MessageDialog(
      webTokenResult.ResponseError.ErrorMessage);
    await dialog.ShowAsync();
  }

}

実行結果は、下図のようになります。

Windows の Service など OS が発行する Protocol を Capture するとわかりますが、Windows 10 では、ログイン時やロック スクリーンからの復帰時などに Azure AD から refresh token を取得しています。そして、「Native Application (Mobile App) で Azure Active Directory に Login するプログラミング」で解説したように、この refresh token を使って さまざまな access token を取得できます。
上記の RequestTokenAsync メソッドによって、Web Account Manager Provider は、grant_type=refresh_token の assertion (すなわち、private key を使用したデジタル署名付きの refresh token) を Azure AD に渡し、Azure AD 側ではデジタル署名と中身のコンテンツ (今回の場合、refresh token, nonce など) を検証して、OK であれば access token を client に返します。
この一連の処理は、Provider が変わると、またフローも変わることでしょう。

開発者は、こうしたフローをまったく理解しなくても、上記のような簡単な手続きで、このように access token を取得できます。

なお、PC のローカル アカウントなど、Azure AD 以外のアカウントでログインしている場合は、Web Account Manager は下図の通り Azure AD のログイン画面を表示します。

また、上記コードで webTokenResult.ResponseData[0].WebAccount.Id にアクセスすることで User の pair-wise id (Sub) を取得できますが、この Id (例えば、y4Pro-6h7o... と仮定します) を使って、以下の通り WebAuthenticationCoreManager から特定の WebAccount を取得し、この account の token を要求することもできます。(この際、必要に応じ、ログイン画面が表示されます。)

. . .
using Windows.Security.Credentials;
. . .

WebAccount specificAccount =
  await WebAuthenticationCoreManager.FindAccountAsync(
    provider,
    "y4Pro-6h7o...");
. . .

また、Azure AD の Account (Work or School Account) ではなく Microsoft Account を使用する場合は、下記の通り実装します。(Microsoft Account が登録されていない場合はエラーになります。)
Provider の種類として「consumers」を指定している点に注目してください。

private async void button_Click(object sender, RoutedEventArgs e)
{
  // get Microsoft Web Account Manager Provider
  var provider =
    await WebAuthenticationCoreManager.FindAccountProviderAsync(
      "https://login.microsoft.com",
      "consumers");

  // request result token to Web Account Manager
  WebTokenRequest webTokenRequest = new WebTokenRequest(
    provider,
    "service::wl.basic::DELEGATION",
    "none");
  WebTokenRequestResult webTokenResult =
    await WebAuthenticationCoreManager.RequestTokenAsync(
      webTokenRequest);

  // show access token
  if(webTokenResult.ResponseStatus == WebTokenRequestStatus.Success)
  {
    var dialog = new MessageDialog("Access Toke : "
      + webTokenResult.ResponseData[0].Token);
    await dialog.ShowAsync();
  }
  else
  {
    var dialog = new MessageDialog(
      webTokenResult.ResponseError.ErrorMessage);
    await dialog.ShowAsync();
  }
}

 

なお、だいぶ安定してきたものの、Microsoft Passport (NGC) には、まだ、いくつかのバグがありますので注意してください。このブログ記載中にも、また NGC がおかしくなってしまいました。もう、通算 4 度目の破壊と OS 入れ直し。。。(酷使しすぎて OS に嫌われてるような気がします。。。)

 

参考情報

//build/ 2015 : Single Sign-On with Secure Authentication (Karanbir Singh)

https://channel9.msdn.com/Events/Build/2015/2-709

//build/ 2015 : Develop Modern Native Applications with Azure Active Directory (Vittorio Bertocci)

https://channel9.msdn.com/Events/Build/2015/2-769

Comments (0)

Skip to main content