最先端の LightSwitch

ソーシャル メディアの資格情報を使用して LightSwitch アプリケーションにログインする

Jan Van der Haegen

 

ますます多くの Web サイトが、Windows Live ID、Yahoo!、Google、Facebook などのサードパーティの Web サイトにユーザーの認証プロセスを委託するようになっています。これらのソーシャル メディア サイトは ID プロバイダーの役割を果たし、署名済みのトークン (ユーザーが主張する身元を証明するキー) を要求元に返します。

LightSwitch は、認証なし、Windows 資格情報、およびフォーム認証の 3 つの認証モードを備えてリリースされました。この LightSwitch により、アプリケーションのプロパティから選択する程度の容易さで、認証モードを選択できるようになります。その後、LightSwitch がデータベースを設定し、ユーザーが選択したログイン プロセスを通じてアクセスできるようにします。開発者が追加作業を行う必要はありません。この認証は高速で便利ですが、拡張性の面ではサポートがなく、明確でもありません。

ただし、サポートがなく、明確ではないといっても、拡張が不可能というわけではありません。LightSwitch の内部構造について少し知識のある開発者であれば、組み込みの LightSwitch 認証を回避する方法がわかるでしょう。今回は、LightSwitch アプリケーションのユーザーが、ソーシャル メディアの資格情報を使用してログインできるようにする方法について説明します。

LightSwitch について具体的な説明を始める前に、セキュリティ トークン サービスについて簡単に紹介します。セキュリティ トークン サービスになじみがない方は、概要として参考にしてください。

セキュリティ トークン サービスについて

つい最近まで、すべてのアプリケーション、Web サイト、または Web サービスは自己完結型で、ユーザーを認証および承認する独自の方法を備えていました。数年前であれば、さまざまなサイトのユーザー名とパスワードの組み合わせを十数個所有しており、他の何よりも "パスワードを忘れた場合" というリンクをよくクリックしていました。サイトの管理者や一般ユーザーは、この問題を不便に感じていました。会社 A と会社 B が提携を結んだことで、会社 B の 100,000 人のユーザーが会社 A のソフトウェアを利用できるようになったとしても、これらのユーザーを 2 つのサイトで重複して管理する必要がありました。

この重複の問題を解決するのは簡単で、ユーザーを認証および承認する要素をアプリケーション、Web サイト、または Web サービスの外に移動し、セキュリティ トークン サービス (STS) という別のサービスに移し変えるだけです。図 1 に、従来のシンプルな STS システムのしくみを示します。

A simple STS scenario
図 1 STS のシンプルなシナリオ

ユーザーとやり取りをするサービスでは、独自のログイン メカニズムを管理する代わりに、STS を信頼して認証および承認を行うことで、ビジネス ロジックにのみ集中することができます。この流れは次のようになります。

  1. ユーザーのブラウザーまたはアプリケーションから、有効なユーザー名とパスワードの組み合わせを渡すことで、STS にセキュリティ トークンを要求します。
  2. STS は、渡されたユーザー名とパスワードを検証します。
  3. STS はセキュリティ トークンを返します。このセキュリティ トークンとは、次の特性を持つキーです。
    • STS から返されたことを証明するため、署名されています。
    • ユーザーが認証済みであること、つまり、ユーザーが主張する身元を証明します。
    • 承認クレームを含みます。承認クレームとは、ユーザーの権限とプロパティ (ユーザーが許可または拒否されている操作) を表す単純な文字列と考えてかまいません。
  4. ユーザーはこのセキュリティ トークンをキーとして使用して、サービスのロックを解除します。
  5. サービスは、トークンの署名に使用された証明書を確認することで、セキュリティ トークンが正規のものであることを確認します。
  6. サービスがクライアントの要求に応答します。

STS を設定して、認証と承認のプロセスを Web サイト、Web サービス、またはアプリケーションから分離すると、STS の設定が構成可能なことから、次のようにメリットをいくつか得られます。

  • 会社 A が所有する複数のアプリケーションが同じ STS を信頼できるようになるため、複数のアプリケーションが 1 つのログイン サービスを使用できるようになります。
  • 1 つの STS が、さまざまな方法でユーザーを認証方法できます。ユーザー名とパスワードの組み合わせ、Windows 資格情報、サードパーティが署名したトークンの信頼などを利用できます。
  • サードパーティのトークンを使用すると、提携した 2 つの会社 (A および B) が抱える重複の問題を解決できます (図 2 参照)。このサードパーティの STS は、元の STS に対する ID プロバイダーの役割を果たします。たとえば、会社 A の STS は、会社 B の STS から返されるトークンを信頼できるようになります。その後、会社 B の従業員は、会社 B の Active Directory に格納されている Windows 資格情報を使用して、STS B を認証できます。ユーザーのブラウザーまたはアプリケーションでは、セキュリティ トークン B を使用して STS A に対する認証を行います。STS A では、STS B によってトークンが署名されたことを認識すると、STS B を信頼して、トークンが間違いなくユーザーが主張する身元を示すと判断します。簡単な対応付けを使用して、ドメイン B のクレームはドメイン A のクレームに関連付けられます。たとえば、トークンにクレーム B\helpdesk が含まれる場合、STS A ではクレーム A\admin を含むセキュリティ トークンを発行します。会社 B の従業員であるユーザーは、このトークンを使用して、会社 A のソフトウェアにアクセスできるようになります。このような使用方法を実現するため、会社 A のソフトウェアに変更を加える必要はありません。会社 A の STS を、会社 B の STS のみ信頼するように構成する必要があります。

A more advanced STS scenario
図 2 STS の高度なシナリオ

アプリケーション内の認証から STS アーキテクチャに切り替えるには多くの処理が必要に見えますが、Microsoft (Windows Live ID STS)、Facebook、Google、Yahoo! など多くの大企業が現在このアーキテクチャを使用しているため、切り替えによるメリットを考えると、労力を費やす価値は十分にあります。

Windows Azure アクセス制御サービス

関心がある方は、STS に関する優れたドキュメントを Microsoft Patterns & Practices サイト (https://msdn.microsoft.com/en-us/library/ff650503.aspx、英語) で閲覧できます。ただし、Patterns & Practices フレームワークを使用して独自の STS のコードを作成するという強い気持ちを抑え、代わりに Windows Azure アクセス制御サービス (ACS) を使用することをお勧めします。Windows Azure ACS はクラウドでホストされる、安価で簡単に構成できるセキュリティ トークン サービスで、Windows Live ID、Facebook、Google、Yahoo! など、他の STS を ID プロバイダーとして信頼するサポートが組み込まれています。

Windows Azure アカウントがあり、Windows Identity Foundation SDK (https://www.microsoft.com/downloads/ja-jp/details.aspx?familyid=c148b2df-c7af-46bb-9162-2c9422208504) を最初のラボ (https://msdn.microsoft.com/en-us/identitytrainingcourse_introtoacslabsv2_topic2 (英語) の演習 1) でダウンロードすると、ユーザーが Windows Live ID、Google、または Yahoo! アカウントを使用して認証できる ASP.NET Web サイトを 30 分以内に作成する方法を確認できます (図 3 参照)。

Logging in to an ASP.NET application using social media credentials
図 3 ソーシャル メディアの資格情報を使用した ASP.NET アプリケーションへのログイン

作成される "Hello social world" ASP.NET アプリケーション (図 4 参照) は、どのようにしたらソーシャル メディアの資格情報を使用した認証を LightSwitch アプリケーションのユーザーに対して有効にできるかという難問を解くための最初の重要な手掛かりです。

“Hello social world” ASP.NET application created in Windows Identity Foundation SDK lab
図 4 Windows Identity Foundation SDK ラボで作成される "Hello social world" ASP.NET アプリケーション

Windows Azure ACS サンプルを拡張する

フォーム認証モードに設定された既存 (または新規) の LightSwitch アプリケーションを用意し、ACS ラボの指示に従って操作したら、ASP.NET アプリケーションと LightSwitch アプリケーションを組み合わせることができるようになります。作成した ASP.NET アプリケーションで、ビジュアル コントロールをすべて削除し、代わりに IFrame を追加します。次に、分離コードを次のコードに置き換えます。

public partial class _Default : System.Web.UI.Page
{
    public static readonly string LightSwitchApplication = 
      "PathToYourLightSwitchAppliction";
    protected void Page_Load(object sender, EventArgs e)
    {
        MyFrame.Attributes["src"] = LightSwitchApplication 
            + "default.htm?UserName="
            + Thread.CurrentPrincipal.Identity.Name.Replace(" ", "");
    }
}

これで、LightSwitch アプリケーションをホストする ASP.NET アプリケーションが作成され、LightSwitch のログイン画面が表示されます (図 5 参照)。

A simple, clean and totally undesirable LightSwitch login screen
図 5 単純でわかりやすいが全体的に地味な LightSwitch のログイン画面

これは、ユーザーにソーシャル メディアの資格情報を使用してログインするように求め、認証済みのユーザー名を (Thread.CurrentPrincipal から) 取得し、その名前を URL を通じて LightSwitch アプリケーションに渡す ASP.NET ページになります。LightSwitch アプリケーションを開始したら、ユーザーには再びログイン画面が表示されます。もちろん、ユーザーは既に資格情報を提供しているため、次は、この LightSwitch のログイン画面を削除し、自動化されたプロセスに置き換えます。これが最も困難な手順です。

LightSwitch ビュー

4 月号の「最先端の LightSwitch」の記事 (https://msdn.microsoft.com/ja-jp/magazine/hh965661.aspx) では、LightSwitch MVVM アーキテクチャについて説明し、ビューに XAML はないという話で終わりました (LightSwitch アプリケーションに XAML を使用しないという考え方は、John Rivard と Karol Zadora-Przyleck によるものです。詳細については、LightSwitch アーキテクチャに関するブログ記事 (https://blogs.msdn.com/b/lightswitch/archive/2010/08/09/the-anatomy-of-a-lightswitch-application-series-part-2-the-presentation-tier.aspx、英語) を参照してください)。もちろん、LightSwitch ビューで XAML がまったく使用されないわけではありませんが、XAML について心配する必要がないというのは確かです。ただし、アプリケーションをカスタマイズする場合は別です。

プロフェッショナル開発者の方や、LightSwitch アプリケーションのグラフィックに変更を加える場合は、ビュー層に関する十分な知識が必要になったり、ビュー層にアクセスすることになります。そこで、ログイン画面を表示する場所と、その方法を確認するため、このビュー層の構成方法を簡単にまとめることから始めます。ビュー層の構成を理解すれば、ログイン画面を、URL を通じて渡されるソーシャル メディアの資格情報を取得するコンポーネントに置き換えることができます。

In-browser LightSwitch application
図 6 ブラウザー内の LightSwitch アプリケーション

標準の LightSwitch アプリケーション (図 6 参照) には、ビュー層を形成するさまざまなコンポーネントが含まれます。

  1. Silverlight アプリケーションをホストする ASP.NET ページ: ソリューション エクスプローラーで LightSwitch アプリケーションを選択し、論理ビューを選択すると、このページ (default.htm) を ServerGenerated プロジェクト (Visual Studio 2010) または LightSwitch プロジェクトのルート (Visual Studio 11 ベータ版) で確認できます。ソリューション エクスプローラーでこのページを確認できるということは、開発者が変更を加えることができることを意味します。
  2. LightSwitch "アプリケーションのブートストラップ": メタデータを読み込む Silverlight アプリケーションでは、(選択したログイン モードに基づき) 必要に応じてログインを処理し、シェル ページに移動します。この実装は、主に、Microsoft.LightSwitch.dll、Microsoft.LightSwitch.Client.dll、Microsoft.LightSwitch.Client.Internal.dll などのアセンブリにあります (MVVM アーキテクチャのメタデータの詳細については、4 月号の「最先端の LightSwitch」の記事 (https://msdn.microsoft.com/ja-jp/magazine/hh965661.aspx) を参照してください)。
  3. シェル ページ: この Silverlight ページにより、コマンド (既定の LightSwitch 1.0 シェルの上部) とナビゲーション メニュー (シェルの左側) の視覚表現が提供され、画面にプレースホルダーが表示されます。既定のシェルの実装は、前の項目で示したアセンブリにあります。ただし、必要に応じて、カスタム シェルを使用することもできます。
  4. 画面: 画面は、メタデータの定義で指定される Silverlight コントロールで構成されます (詳細については、4 月号の「最先端の LightSwitch」の記事を参照してください)。ControlTemplate またはコントロールの外観を定義する XAML が、テーマ別に定義されます。既定のテーマの実装は、前の項目で示したアセンブリにあります。ただし、必要に応じて、カスタム コントロールやカスタム テーマを使用することもできます。

プロフェッショナル開発者の大半の方が抱いているイメージとは異なり、LightSwitch アプリケーションは生成済みのクローズ型のアプリケーションではありません。確かに、LightSwitch アプリケーションは部分的には生成済みですが、クローズ型のアプリケーションということは決してありません。ASP.NET ページは、開発者のニーズに合わせて (前の一覧の項目 1 参照)、シェル拡張 (項目 3)、テーマ拡張 (項目 3 および 4)、コントロール拡張 (項目 4)、または Silverlight カスタム コントロール (項目 4) を使用するように変更できます。開発者は、LightSwitch アプリケーションの視覚要素、つまり、置き換える必要があるログイン ページを含むアプリケーションのブートストラップ (項目 2) 以外の要素を細かく制御できます。

LightSwitch アプリケーションのブートストラップでログイン ページに移動すると、Silverlight がイベントを発生します。このイベントのイベント ハンドラーを追加することで、LightSwitch ログイン ロジック全体を迂回できます。ログイン ロジックが発生しないようにすることは不可能なので、ログイン ページを置き換えるのではなく、LightSwitch のブートストラップでログイン ページに移動しようとするイベントを利用して、アプリケーション フローを制御します。

図 7 のコードを、Application_Initialize 拡張ポイント (コードの作成) に配置します。これは、ログイン ページが表示される前に唯一発生する LightSwitch 拡張ポイントになります。

using System; 
using System.Linq; 
using System.IO; 
using System.IO.IsolatedStorage; 
using System.Collections.Generic; 
using Microsoft.LightSwitch; 
using Microsoft.LightSwitch.Framework.Client; 
using Microsoft.LightSwitch.Presentation; 
using Microsoft.LightSwitch.Presentation.Extensions; 
using System.Windows.Controls; 
using Microsoft.LightSwitch.Runtime.Shell.Internal.Implementation; 
using Microsoft.LightSwitch.ApplicationInfrastructure.Utilities.Internal; 
using Microsoft.LightSwitch.Runtime.Shell.ViewModels.Login; 
using Microsoft.VisualStudio.ExtensibilityHosting; 
namespace LightSwitchApplication 
{ 
    public partial class Application 
    { 
        Frame rootFrame = null; 
        partial void Application_Initialize(){ 
        Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() => { 
                rootFrame = 
                              ((Page)((ContentPresenter)System.Windows.Application.Current.RootVisual) 
                              .Content).Content as Frame; 
                if (rootFrame != null) 
                    rootFrame.Navigated += new 
                        System.Windows.Navigation.NavigatedEventHandler( 
                            rootFrame_Navigated 
                    ); 
            }); 
        } 
        void rootFrame_Navigated(object sender, 
            System.Windows.Navigation.NavigationEventArgs e) 
        { 
            if (e.Content is LoginPage) { 
                rootFrame.Navigated -= rootFrame_Navigated;   
                string userName = null; 
                if (QueryStringHelper.TryGetValue("UserName", 
                    out userName)) 
                { 
                    ILoginViewModel vm = 
                        VsExportProviderService.GetExportedValue<ILoginViewModel>(); 
                    vm.UserName = userName; 
                    vm.Password = "RandomPassword"; 
                    vm.LoginCommand.Execute(vm); 
                } 
            } 
        } 
    } 
}

図 7 LightSwitch のログイン画面の迂回

Application_Initialize メソッドでは、Silverlight のルート フレームを見つけ、その移動されるイベントへのイベント ハンドラーを追加します。スレッドの問題を回避するため、この処理を LightSwitch のメイン ディスパッチャーで実行します。

このイベントが発生したら、移動先のページが LoginPage かどうかを確認します。LoginPage の場合は、イベント ハンドラーのガベージ コレクションが行われない場合の少量のメモリ リークを回避するために、イベント ハンドラーを削除するのがベスト プラクティスです。LightSwitch の QueryStringHelper クラスを使用して、ASP.NET ページから URL で渡された UserName を取得します。この情報が有効であれば、LightSwitch の ILoginViewModel 実装を使用して、UserName とランダムなパスワードを渡し、この ViewModel で LoginCommand を実行して、ログインを処理します。

技術の簡単な復習

以上で、ログイン プロセスを Windows Azure ACS に委任する ASP.NET Web アプリケーションを設定しました。単純な構成なので、アクセスするソーシャル メディア ネットワークにこのアプリケーションを委任できるようになります。ASP.NET アプリケーションから LightSwitch アプリケーションに資格情報が渡されます。この LightSwitch アプリケーションには、既定のログイン画面ではなく、これらの資格情報を使用するカスタム コードを用意しました。

賢明な開発者へのアドバイス

LightSwitch はこのシナリオを既定ではサポートしませんが、ここで紹介したように、コードにいくつか小さな変更を加えることで、ユーザーがソーシャル メディア プラットフォームを使用してログインできるようになります。これを行う場合は、以下に示す注意事項に留意してください。

LightSwitch の LoginPage を迂回する処理は、正式にはサポートされておらず、LightSwitch の内部実装を使用します。そのため、コードは、LightSwitch フレームワークの中でもパブリック API に含まれない部分に大きく依存します。LightSwitch チームが今後のリリースでパブリック API の必要性を感じたら、状況は変わる可能性があります。厳密に言えば、内部実装の使用は、EULA 違反と考えられます。そのため、実を言うと、この記事は読むべきではありません。お使いのブラウザーは 5 秒以内に自動的に消滅します。

今回はステップ バイ ステップ ガイドではありません。ユーザーが職場にいても自宅にいても、ソーシャル メディアを使用していようといまいと、使い慣れた一貫性のあるログイン画面を表示する LightSwitch アプリケーションを、どのようにして作成するかという難問を解くための重要な手掛かりについて説明しています。次は、実装のセキュリティについて検討する必要があります。たとえば、UserName をプレーンな文字列として URL で送信するのではなく、暗号化します。できれば、URL が他のユーザーに乗っ取られたり、再利用されたりしないように、時間の概念を含めます。ハードコードされた RandomPassword ではなく、元の UserName のハッシュを使用することを検討します。

Visual Studio 11 ベータ版の LightSwitch 2.0 を使用する場合、ドメイン データを OData エンドポイントとして公開します。これにより、ドメイン データは、Windows Phone アプリケーションなど、Silverlight クライアント以外のさまざまなクライアントで使用できます (Windows Phone アプリケーションで LightSwitch OData サービスを使用する方法については、3 月号の記事 (https://msdn.microsoft.com/en-us/magazine/hh875176.aspx、英語) を参照してください)。これらのサービスは、Windows Azure ACS でセキュリティが確保されるのではなく、選択する LightSwitch 認証 (認証なし、Windows 資格情報、またはフォーム認証) によってセキュリティが確保されます。

ソーシャル メディアのセキュリティ トークンと Windows Azure ACS セキュリティ トークンの対応について調べると、Windows Live ID セキュリティ トークンに "名前" のクレームが含まれないことがわかります。選択する ID プロバイダー (ソーシャル メディア プラットフォーム) に応じて、ニーズに合った固有のクレームを特定します。図 8 に、Google、Yahoo!、および Windows Live ID を ID プロバイダーとして選択する場合に有効なクレームの候補を提供する "nameidentifier" クレームを示します。

The ACS rule map
図 8 ACS 規則の対応付け

上記の注意を読んで理解していただいたら、STS というクレーム ベースのセキュリティと LightSwitch を統合したすばらしい世界をぜひお楽しみください。最近の調査で、従業員がソーシャル メディアの資格情報を使用するときは、仕事でユーザー名とパスワードを共有するときよりも 5 倍近く慎重になっていることがわかります。このことを除けば、ユーザーはユーザー名とパスワードの組み合わせをほんの数個覚えるだけで、それを使用してさまざまなアプリケーションにログインできるため、とても便利です。私は、実績ある LightSwitch ネットワークである MyBizz Portal (http://www.codeproject.com/Articles/319456/MyBizz-Portal-The-smallest-LightSwitch-application、英語) で LightSwitch 1.0 を使用したときから、このシングル サインオンの手法を使用してきました。ユーザーがソーシャル メディアの資格情報を使用して、ビジネス アプリケーションにログインできるようにして以来、ユーザーから優れたフィードバックが提供されるようになりました。

Jan Van der Haegen は、コーヒーをソフトウェアに変える、環境に優しいオタクです。彼は優しい夫であり、Centric Belgium の国際チームの誇り高きメンバーであり、自身のコーディング経験に関するブログを管理する .NET テクノロジ (特に、Visual Studio LightSwitch) について学習することに熱中しています。彼の最近の出来事は、http://www.switchtory.com/janvan (英語) で公開されています。

この記事のレビューに協力してくれた技術スタッフの Paul Patterson に心より感謝いたします。