連載:Microsoft技術におけるアイデンティティ連携開発のいま(2)
.NETで使えるアイデンティティ連携のためのライブラリまとめ(後編)
アイデンティティ連携で使用可能なライブラリやサービスなどをまとめる記事の後編。今回はAzure Active Directoryのアイデンティティ連携を中心に解説。
【注意】本稿は2013年8月7日に大幅に改訂しました
ライブラリの名称(「Windows Azure Authentication Library」→「Active Directory Authentication Library」)や仕様が変更されたのに伴い、本稿の内容をその最新状況にアップデートしました。
前回は、アイデンティティ連携で使用可能な各技術要素(使用可能なライブラリや、サービスなど)として、オーソドックスなソーシャル・アイデンティティ(Facebookのアカウント、Googleアカウント、Microsoftアカウントなど)との連携を行うDotNetOpenAuthについて説明した。今回は引き続き、Microsoft Azure(旧称:Windows Azure) Active Directoryのアイデンティティ連携など、さらに応用的なテーマについてまとめる。
なお、開発言語によって使用するライブラリなどは異なるが、本稿では、サーバー側の実装基盤として.NET(プログラミング・サンプルはC#言語)を前提に記載する。
Azure Active Directory ―― Access Control
前回はDotNetOpenAuthが、OAuthやOpenIDのプロトコル・ライブラリの性質を持つことを解説した。だが例えば、Windows Server Active Directory、および、そのアイデンティティ連携のためのActive Directoryフェデレーション・サービス(Federation Services)バージョン2.0または2.1(以降、単に「AD FS 2.0」と記載)のような、性質の異なる(エンタープライズ向けの)アイデンティティ・プロバイダーが入ってきた場合を考えてみよう。この場合、残念ながらDotNetOpenAuthで扱うことはできない。なぜなら、使用しているプロトコルが、全く異なるためだ。
また、前回のカスタムOpenIdClientのサンプルからも分かるように、クレーム情報の取得についても、対象となるアイデンティティ・プロバイダー(Facebook、Googleなど)に応じて、異なるコードを作成する必要がある。対応するアイデンティティ・プロバイダーが変更(追加など)されるたびに、アプリケーションの再コンパイルとテストを行って、プロダクション環境にリリースする必要も出てくるだろう。
そこで、クラウド上にワン・ホップのサービス(=ゲートウェイのようなもの)を立てて仲介することで、これらの多くの課題を解決しようとしているのが、Azure Active Directoryの「Access Control」と呼ばれるサービスだ(以降、単に「Access Control」と記載。従来、「Azureアクセス制御サービス: Azure Access Control Services」、または「ACS」と呼んでいたサービスだ)。
Access Controlは、使用するアイデンティティ・プロバイダー(Google、Facebook、Active Directoryなど)と、それを使用するWebアプリケーション(Relying Party)の間を仲介するセキュリティ・ゲートウェイ(=「セキュリティ・トークン・サービス: Security Token Service」。以降、単に「STS」と呼ぶ)として機能する。インストール・ベースではなく、契約ベースで利用可能なAzure上のサービスであり、「名前空間」と呼ばれる論理的な領域を作成することで、このAccess Control(および、そこで使用する独自のドメイン)が使用可能になる。
アイデンティティ・プロバイダー(Google、Facebookなど)からは、Access Controlは「Relying Party」(すなわち、そのアイデンティティ・プロバイダーを使用しているアプリケーション)として見えている(下の図を参照)。一方、接続するWebアプリケーション(Relying Party)からは、Access Controlは「アイデンティティ・プロバイダー」として見えているのだ。
例えば、Access Controlを介してGoogleアカウントを使用するWebアプリケーションの典型的な認証フローは、下記のとおりとなる。
(1)エンド・ユーザーがWebアプリケーション(=上の図の左にある「Application1」)に接続すると、認証チケットがないためAccess Controlに遷移する。
WebアプリケーションとAccess Controlの間の、このやりとりでは、WS-Federationが使用される。
(2)Access Controlは、使用するアイデンティティ・プロバイダーの選択画面(下の画面)をエンド・ユーザーに表示する(ただし、使用しているアイデンティティ・プロバイダーが1つの場合、この画面は表示せずにアイデンティティ・プロバイダーに遷移する)。
(3)エンド・ユーザーが選択したアイデンティティ・プロバイダー(今回の場合は、Googleアカウント)に遷移する。そして、アイデンティティ・プロバイダー(Googleアカウント)では、エンド・ユーザーにログイン画面を表示し、認証後はAccess Controlに戻ってくる。
このGoogleアカウントとAccess Control間でのやりとりでは、OpenIDが使用される(Googleアカウントのドメインでは、クッキーなどの認証チケットが発行されるので、次回以降、Googleアカウントに認証が要求されても、ログイン画面を表示せずに、認証済みとして戻される)。
(4)Access Controlでは、アイデンティティ・プロバイダーから受け取った認証情報を基に、WS-Federationを使用して呼び出し元のWebアプリケーション(=先ほどの概念図の左にある「Application1」)に戻す。
(5)Webアプリケーションは、この渡された内容を確認して、問題なければ認証チケット(実体は、クッキー)を発行する。
なお、上述のアイデンティティ選択の画面は「アイデンティティ・セレクター(Identity Selector)」と呼ばれており、このUI(見た目)は開発者でカスタマイズ可能だ。
このフローから分かるように、開発者が作成するアプリケーション(=上掲の概念図の左にある「Application1」)は、アイデンティティ・プロバイダーとしてAccess Controlのみを知っていればよい。Access Controlでは、アイデンティティ・プロバイダーの追加や削除は、Access Controlの設定変更のみで対処可能で、アプリケーション側のコードに影響しない(ただし、実際の開発では、開発の初期段階に入念に設計しておかないと、アイデンティティ・プロバイダーの追加とともに細かな修正が必要になる場合があるので注意してほしい)。
また、GoogleアカウントやAD FS 2.0など、全く性質の異なるアイデンティティ・プロバイダーを組み合わせる場合も、最終的にAccess Controlが、プロトコルや、その中で使用するセキュリティ情報のフォーマットなどを統一するため、アプリケーション側はこうした性質の差異を意識してプログラミングする必要もない。
さらに、アイデンティティ・プロバイダーごとにクレーム情報(例えば「姓」「名」「役職」などの追加の属性情報)の名前などが異なっている場合も、Access Controlでクレーム変換が定義可能であり、アプリケーション側でこの差異を意識せずに認可のコード(例えば、一定の役職でなければ使えない操作など)を記述することも可能だ。
なお、変換(統一化)するプロトコルは、歴史的経緯もあり、現在もWS-Federation(WS-Fed)が使用されているが、変換するセキュリティ・フォーマットは、アプリケーション(Relying Party)ごとに選択が可能であり、次の画面のように「SAML(SAML1.1、SAML2.0)」「SWT(Simple Web Token)」「JWT(Json Web Token)」から選べる(なお、ここで記載している「SAML」とは、「SAML Protocol」ではなく、セキュリティ・フォーマットとしての「SAML Assertion」を指している)。
Access Controlでは、主にAccess Controlに対応した(プログラマーが新規に作成する)カスタム・アプリケーションが接続することを想定しているため、アプリケーション(Relying Party)側はWS-Federationのみで十分だ。しかし、このゲートウェイ(Access Control)を使うアーキテクチャを採用すれば、ゲートウェイ(ハブ)の作り方次第では、多様な既存のアプリケーション(Relying Party)と柔軟に接続することも可能となるだろう。実際、アイデンティティ関連のサード・パーティ製品のいくつかは、こうした同様のアーキテクチャを採用して、アイデンティティに関するさらに高度な問題解決を可能にしているものもある(ここでは、これらの製品についての説明は省略する)。
【注意】Access Control(ACS)の今後について
後述するAzure Active DirectoryのDirectory機能は、今後も積極的に機能追加が行われる予定であり、将来、Azure Active Directory(のDirectory)でも、Access Control(ACS)と同等の機能の提供を予定している。これからACSの使用を検討されている方は、後述する Azure Active Directory(のDirectory)で実現可能かを検討してほしい (詳しくは、Active Directory Team Blogの記事(英語)の記載を参照されたい)。
Windows Identity Foundation(WIF)によるWS-Federation/WS-Trust連携
さて、前述のとおり、Access Controlでは統一のプロトコルやセキュリティ・フォーマットに変換を行うため、シングル・サインオン(以降、SSO)の実装や、クレーム情報(=渡される名前、メール・アドレス、役職などの属性情報)の解析などを行うアプリケーション(Relying Party)のプログラマーは、この単一のプロトコルとフォーマットを扱えばよい。すなわち、開発の際には、統一のプロトコルであるWS-Federationを扱えるライブラリやSDKが必要だ。
マイクロソフトでは、これまで、統合アイデンティティ(Federated Identity)の中核製品として、AD FS 2.0やAzure Active Directory Access Control(旧 ACS)などのWS-FederationやWS-Trustを使用した製品群を提供していた経緯から、この連携開発を行うための.NETのライブラリとして、Windows Identity Foundation(以降、単に「WIF」と記述)を提供してきた。そして現在(最新の.NET 4.5では)、このライブラリは、.NET Frameworkに既定で含まれる標準ライブラリとなっている。WIFは、前述したDotNetOpenAuthとは対極に、WS-FederationとWS-Trustのプロトコル・ライブラリの性質を強く持つ。このため、Access Controlとの連携以外にも、例えば、AD FSそのもの(AD FS 2.0も、同様に、WS-FederationとWS-Trustを扱う)に対して直接、フェデレーションを行う際にも、このライブラリを使用できる。
さて、恐らく、Access Controlとの連携開発で最もニーズが多いプログラミングは、SSOの実装であろう(もちろん、そのほかのさまざまな連携シナリオも考えられる。それについては、次回以降で解説する予定だ)。実は、SSOをWIFで実装するだけであれば、ほとんどプログラム・コードを書く必要はなく、「Identity and Access Tool」というVisual StudioのアドオンをNuGetから入手することで、このツールを使って自動的にWIFのコードが生成できるようになっている。出力されるコードは、C#などのロジックではなく、構成ファイル(Web.config)に静的な構成情報(XML)として出力される(プログラマーは、必要に応じ、この構成を変更できる)。この開発方法は、さまざまな場所で紹介されているので、本稿では開発手順の解説は省略する(例えば、著者のブログ「.NET Framework 4.5 の WIF と "Identity and Access Tool"」を参照していただきたい)。
なお、セキュリティ・フォーマットの処理について、前述したSAML AssertionはWIFで処理することが可能だが、JWTについてはNuGetで配布されている「JSON Web Token Handler For the Microsoft .Net Framework 4.5」(本執筆時点では開発者プレビュー版)を使用することで処理可能だ。
それでは、Azure Active DirectoryのDirectory(ディレクトリ。以降、単に「Azure Active Directory」または「Directory」と表現)について解説しよう。
Azure Active Directory ―― Directory(ディレクトリ)
前述したようにAccess Controlは、複数のアイデンティティ・プロバイダーと複数のアプリケーション(Relying Party)を柔軟に接続するゲートウェイ(すなわち、STS)の役割を果たしていたが、ここで紹介するDirectory(ディレクトリ)は、ユーザー情報の保持(管理)も含む、クラウド上で使えるアイデンティティ・プロバイダーそのものを提供する機能だ(あまり推奨はしないが、このDirectoryをAccess Controlのアイデンティティ・プロバイダーの1つとして接続することもできる)。
アイデンティティ・プロバイダーそのものを提供するだけなら、例えば前述のDotNetOpenAuthを使っても構築できるが、Directoryを使ういくつかの重要なメリットがあるので、ここでは、この特徴を3つに分けて紹介しておこう。
まず、インストール・ベースではなく、クラウド上に「サービス」として提供されているという点だ。ある企業や団体で使用するアイデンティティ・プロバイダーを提供したい場合、わざわざソフトウェアのインストールや、ライブラリ(DotNetOpenAuthなど)を使ったプログラミング(構築)を行う必要はない。契約ベースで使うことができ、契約ごとにマルチテナントで利用できる。
2つ目の特徴は、さまざまな周辺環境に既定で対応できるという点だ。例えば、DotNetOpenAuthを使ってOpenIDプロバイダーを自前で構築した場合、SAML-P(SAMLプロトコル)やWS-Federationに対応することはできない(別途開発が必要だ)。また、OAuth 2.0、OpenID Connectなど、登場する新しい仕様に都度対応するのも容易なことではないだろう。Directoryは、すでにWS-FederationとSAML-Pに対応しており、今後もOpenIDへの対応が予定されているなど、さまざまなプロトコル仕様に対応することが計画されている(ただし、現在、SAML-Pの全てのシナリオに対応しているわけではないので注意してほしい)。クラウド上で提供されるサービスなので、サービスのバージョン・アップも自動で行われる。また、Directoryと連携するサンプル・コードも、.NET(C#、Visual Basic)だけでなく、PHP、Java用のサンプル・コードを同時に提供するなど、特定の環境に特化せず(オープンに)使われることを目指している。
最後の重要な特徴として、マイクロソフトが提供するクラウド・ベースのアプリケーションの統一的アイデンティティ基盤を目指しているという点だ。2013年2月にリリースされた新Office 365や最新のDynamics CRM Onlineなどは、既に、アイデンティティ基盤として、このAzure Active Directory(Directory)を使用している。特に、SharePoint OnlineなどOffice 365で動作するWebアプリケーション(Relying Party)とのSSOのニーズは高く、このAzure Active Directory(Directory)を使用することで、容易にこうしたOffice 365のアプリケーションとSSOを行うカスタム・アプリケーションが作成できる(次の図を参照)。
これまでのOffice 365のユーザー・リポジトリーは、いわば「Office 365のためのユーザー・リポジトリー」であったが、新Office 365からは、中小規模の組織で統一的に使用可能なエンタープライズ・ディレクトリとして使用することができるわけだ。
Directoryでは、まだいくつかの管理操作(特に、開発者が使用する高度な管理操作)にWindows PowerShellが必要だ(ここでは、こうしたWindows PowerShellを使用したDirectoryの開発者向けの操作の解説は省略するが、筆者のブログ「Azure Active Directory と事前準備」を参照していただきたい)。このWindows PowerShellのコマンドは、もともとOffice 365で提供されていたWindows PowerShellコマンドを拡張したものであり、こうした点からも実は、Directoryが、Office 365が従来から使用していた認証リポジトリー(=ユーザー・リポジトリー)の拡張となっている点が分かる。
例えばOffice 365では、従来からAD FS 2.0(および、オンプレミスのWindows Server Active Directory)とのフェデレーション(=ユーザー認証時の接続)と同期(=ユーザー情報、属性情報などのリポジトリー間の同期)が可能であったが、Directoryでもこうした機能は踏襲されている。
Azure Active Directory(のDirectory)との連携開発
開発者(プログラマー)が、このDirectoryとSSOに対応したアプリケーションを開発する場合、前述の「Identity and Access Tool」を使って接続することも可能だが、「ASP.NET and Web Tools 2012.2」と「Microsoft ASP.NET Tools for Windows Azure Active Directory - Visual Studio 2012」をインストールすることで利用可能な[Enable Windows Azure Authentication]メニュー(次の画面を参照)を使用する方が便利だ。
本来、Directoryを使用したSSOを実装するには、あらかじめ、管理画面やWindows PowerShellを使ってDirectory側にいくつかの設定が必要だが、このメニューを使用すると、こうした事前準備も、この機能が自動で実施してくれる(なお、この機能は当初、「ASP.NET and Web Tools 2012.2」と共にリリースされる予定であったが、Azure Active Directoryとのリリース時期の相違から、結局、「Microsoft ASP.NET Tools for Windows Azure Active Directory - Visual Studio 2012」としてリリースされることになった)。
また、Directoryでは、「Azure Active Directory Graph(グラフ)」と呼ばれるREST APIのエンドポイントが提供されており、このエンドポイントを呼び出すことで、ユーザー情報の追加・変更・削除や、差分情報の更新による同期の仕組みなどをプログラミングできるようになっている。ユーザー情報を一覧表示するような機能拡張や、独自な管理機能を提供する場合など、さまざまなケースでこのAzure Active Directory Graphが活用できるだろう(このGraphを使用する際も、認証には、後述の Active Directory Authentication Libraryを使用するとよい。こうしたserver-to-serverの接続シナリオについては、次回以降で解説する予定だ)。
Active Directory Authentication Library(ADAL)―― シナリオ・ベースのヘルパー・ライブラリ
WIFがWS-Federation、WS-Trustのプロトコル・ライブラリの性質を持つのに対し、Azure Active Directoryにおけるシナリオ・レベルの実装をサポートするのが、Active Directory Authentication Library(以降、単に「ADAL」と記載)だ。このライブラリは、次の画面のようにNuGetから取得できる(ただし、現在、まだプレビュー版なので注意してほしい)。
例えば、Azure Active Directoryにおけるアプリケーション(Relying Party)を、Webアプリケーションではなくデスクトップ・アプリなどのネイティブ・アプリケーションから利用する場合を考えてみよう。認証後は、同じテナント(Directory)に含まれるほかのサービス・アプリケーション(Relying Party)を、認証で取得した情報(=トークン)を使って呼び出す。つまり、Webブラウザーを使用したSSOとは異なるが、Azure Active Directory(の同一のテナント)を使用するアプリケーション(Relying Party)同士で認証を介して連携するようなケースだ。
この場合、Webブラウザーのアプリケーションではないため、以下の手順でプログラミングするのが一般的だ。
- Webブラウザーで認証の流れを処理できるように、ネイティブ・アプリケーションにWebブラウザー用のコントロールなどを準備しておく
- 上記のWebブラウザー・コントロールを使って、Azure Active Directoryに接続する。Webブラウザー・コントロール内でログイン画面を表示して、認証処理が実行される。
- 認証完了後、必要なトークン情報が渡されるので、アプリケーションでは、プログラムを使って、このトークンを取り出す
- あとは、受け取ったトークンを使って、サービス(別のRelying Party)を呼び出す(呼び出しの際のHTTPヘッダーに、このトークンの情報を付与する)。サービス側では、このトークンの妥当性を検証し、問題なければ結果を返す(問題があれば、HTTP 401の権限エラーを返す)
次回(第3回)で、このフローの詳細を解説する予定だが、プログラミング経験のある人なら想像できるとおり、そこそこ面倒なプログラミングが必要だ。しかし、Active Directory Authentication Library(ADAL)を使用した場合には、これをわずかなコードで処理できる。下記のコード例のとおり、トークンの取得は、わずか2行で実現できる(下記のコードは、デスクトップ・アプリでボタンを押した際の処理を記述している)。なお、下記のコードを動作させるには、あらかじめ、Azure Active Directoryへのアプリケーション(=Relying party、証明書利用者アプリケーション)の登録や権限設定が必要なので注意してほしい(こうした登録方法については、著者のブログ「Native Application で Azure Active Directory に Login するプログラミング」に記載した)。
using System.Net;
using System.IdentityModel.Clients.ActiveDirectory;
private void Button_Click(object sender, RoutedEventArgs e)
{
// AADと連携して認証、およびトークンを取得
AuthenticationContext authCtx =
new AuthenticationContext("https://login.windows.net/o365demo01.onmicrosoft.com");
AuthenticationResult authRes = authCtx.AcquireToken(
"testapp2/localhost", // resource name to access
"5bbe4005-5e99-4a51-9846-f0dd9a02549a", // client id
new Uri("http://localhost/testapp1")); // redirect uri
// 取得したトークンを使用してサービスを呼び出し
HttpWebRequest request =
WebRequest.Create("https://localhost/testapp2/items/3") as HttpWebRequest;
request.Method = "GET";
request.Headers["Authorization"] = authRes.CreateAuthorizationHeader();
request.ContentType = "application/json";
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
……省略……
}
|
このアプリケーションを実行してボタンをクリックすると、次の画面のとおり、Azure Active Directoryのログイン画面がWebブラウザーで表示され、認証が完了すると、このブラウザー画面を閉じる(以降は、内部で、サービスの呼び出しを行う)。
この動きを制御しているのは、上記のコードの2行目のAcquireTokenメソッドだ。このメソッドは、まさに、こうしたネイティブ・アプリケーションからの使用を想定して提供されており、面倒な手続きは、全てのこのメソッドの中に隠ぺいされているのだ。
このように、ADAL(Active Directory Authentication Library)は、「利用シナリオ」を想定して提供されているライブラリだ。一般的なWebアプリケーションでは、Webブラウザーが面倒な認証のフローを代行してくれるが、特に、ここで紹介したようなネイティブ・アプリケーションや、UI(ユーザー・インターフェイス)を持たないサービス・アプリケーションなどでは重宝するはずだ。
また、ADAL(Active Directory Authentication Library)は、その名のとおり、Active Directoryに特化したライブラリだ。最新のWindows Server 2012 R2のAD FS(Active Directory Federation Services)では、OAuth のエンドポイントが提供されていて、ADALは、AD FSとAzure Active Directory の双方の認証で使用することができる(詳細は、Active Directory Team Blogの記事(英語)を参照していただきたい)。
■
以上、前回~今回では、アイデンティティ連携開発で使用できる基本的なコンポーネントや用語(開発で使用できるインフラ、ライブラリなど)を解説した。次回以降では、これらを使用して、現実に必要となるさまざまな利用シナリオをどのように実現するか、実際のプログラム・コードを見ながら解説したい。
1. .NETで使えるアイデンティティ連携のためのライブラリまとめ(前編)
Webアプリなどで、Facebook、Google、Twitter、企業内のActive Directoryなどの各アイデンティティ基盤と連携するための各技術(ライブラリやサービス)を、開発者視点で整理する連載スタート。
2. 【現在、表示中】≫ .NETで使えるアイデンティティ連携のためのライブラリまとめ(後編)
アイデンティティ連携で使用可能なライブラリやサービスなどをまとめる記事の後編。今回はAzure Active Directoryのアイデンティティ連携を中心に解説。
3. カスタム・アプリケーションによる認証フローとプログラミング
ネイティブ・アプリのプログラム・コードから認証を行う方法とは? Azure Active Directoryを例に、OAuth 2.0をベースにした、プラットフォームに依存しない新しい手法を考察する。
4. Azureの認証におけるその他サービス ~ Azureモバイルサービス、多要素認証
最終回。Azureモバイルサービスや、多要素認証など、これまでの連載で取り上げなかった、認証に関わる先進的な技術を簡単に紹介する。