クイック スタート: Windows ストア アプリ間でのユーザー証明書の共有 (HTML)
証明書認証は、ユーザーの認証時に高レベルの信頼性を提供します。ユーザー ID とパスワードの組み合わせよりも安全な認証を必要とするアプリでは、証明書を認証に使うことができます。場合によっては、複数の Windows ストア アプリから、複数のサービスのグループに対してユーザーを認証することがあります。このクイック スタートでは、1 つの証明書を使って複数の Windows ストア アプリを認証する方法と、セキュリティで保護された Web サービスにアクセスするための証明書をユーザーがインポートできるようにする便利なコードを記述する方法について説明します。
Windows ストア アプリでは、証明書を使って Web サービスから認証を受けることができます。さらに、複数の Windows ストア アプリが、証明書ストアにある 1 つの証明書を使って同じユーザーを認証できます。証明書がストアに存在しない場合は、PFX ファイルから証明書をインポートするコードをアプリに追加できます。
目標: セキュリティで保護された複数の Web サービスに対して、複数の Windows ストア アプリから使えるような方法で、1 つの証明書を使ってユーザーを認証します。
必要条件
このクイック スタートはあくまでもサンプルであり、ローカル コンピューターの Microsoft インターネット インフォメーション サービス (IIS) を使います。このクイック スタートを実行するには、以下が必要です。
- Windows 8.1
- Microsoft Visual Studio
- Microsoft Internet Information Server (IIS)
手順
1. IIS とクライアント証明書マッピングの有効化
IIS は、既定では有効になっていません。IIS を有効にするには、Windows のコントロール パネルを使います。
- Windows のコントロール パネルを開き、[プログラム] をクリックします。
- [Windows の機能の有効化または無効化] をクリックします。
- [インターネット インフォメーション サービス] を展開して、[World Wide Web サービス] を展開します。[アプリケーション開発機能] を展開して、[ASP.NET 3.5] と [ASP.NET 4.5] を選びます。 これらを選ぶと、自動的に [インターネット インフォメーション サービス] が有効になります。
- [OK] をクリックして変更を適用します。
2. セキュリティで保護された Web サービスの作成と発行
この手順では、セキュリティで保護された Web サービスを作成して IIS サーバーに発行します。
管理者として Visual Studio を実行し、スタート ページで [新しいプロジェクト] を選びます。Web サービスを IIS サーバーに発行するには、管理者のアクセス権が必要です。[新しいプロジェクト] ダイアログで、フレームワークを [.NET Framework 3.5] に変更します。[Visual C#]、[Web]、[Visual Studio]、[ASP.NET Web サービス アプリケーション] の順に選びます。アプリケーションに "FirstContosoBank" という名前を付けます。[OK] をクリックしてプロジェクトを作成します。
Service1.asmx.cs ファイルで、既定の HelloWorld Web メソッドを次の "Login" メソッドに置き換えます。
[WebMethod] public string Login() { // Verify certificate with CA var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2( this.Context.Request.ClientCertificate.Certificate); bool test = cert.Verify(); return test.ToString(); }
Service1.asmx.cs ファイルを保存します。
ソリューション エクスプローラーで、"FirstContosoBank" アプリを右クリックし、[発行] をクリックします。
[Web の発行] ダイアログで、新しいプロファイルを作って "ContosoProfile" という名前を付けます。[次へ] をクリックします。
次のページで、IIS サーバーのサーバー名を入力し、"Default Web Site/FirstContosoBank" のサイト名を指定します。[発行] をクリックして Web サービスを発行します。
3. クライアント証明書認証を使うための Web サービスの構成
この手順では、IIS マネージャーを使い、先ほど発行した Web サービスを構成して、クライアント証明書を要求するように設定します。
- インターネット インフォメーション サービス (IIS) マネージャーを実行します。
- IIS サーバーのサイトを展開します。[Default Web Site] で、新しい "FirstContosoBank" Web サービスを選びます。[操作] セクションで、[詳細設定] を選びます。
- [アプリケーション プール] を [.NET v2.0] に設定し、[OK] をクリックします。
- インターネット インフォメーション サービス (IIS) マネージャーで、IIS サーバーを選んで [サーバー証明書] をダブルクリックします。[操作] セクションで、[自己署名入り証明書の作成] を選びます。証明書のフレンドリ名として「"ContosoBank"」と入力し、[OK] をクリックします。これにより、IIS サーバーで使われる新しい証明書が "<サーバー名>.<ドメイン名>" の形式で作成されます。
- インターネット インフォメーション サービス (IIS) マネージャーで、既定の Web サイトを選びます。[操作] セクションで [バインド] を選び、[追加] をクリックします。種類として "https" を選び、ポートを "443" に設定して、IIS サーバーの完全なホスト名 ("<サーバー名>.<ドメイン名>") を入力します。SSL 証明書を "ContosoBank" に設定します。[OK] をクリックします。[サイト バインド] ウィンドウの [閉じる] をクリックします。
- インターネット インフォメーション サービス (IIS) マネージャーで、"FirstContosoBank" Web サービスを選びます。[SSL 設定] をダブルクリックします。[SSL が必要] をオンにします。[クライアント証明書] で [必要] を選びます。[操作] セクションで、[適用] をクリックします。
- Web サービスが正しく構成されたことを確認するには、Web ブラウザーを開き、Web アドレスとして "https://<サーバー名>.<ドメイン名>/FirstContosoBank/Service1.asmx" を入力します。たとえば、"https://myserver.example.com/FirstContosoBank/Service1.asmx" のように指定します。Web サービスが正しく構成されていれば、Web サービスにアクセスするためのクライアント証明書を選ぶように求められます。
前の 2 つのセクションの手順を繰り返すことで、同じクライアント証明書を使ってアクセスできる複数の Web サービスを作成できます。
4. 証明書認証を使う Windows ストア アプリの作成
これでセキュリティで保護された Web サービスが 1 つ以上できたので、証明書を使ってこれらの Web サービスから認証を受ける Windows ストア アプリを作成できます。HttpClient オブジェクトを使って認証 Web サービスへの要求を作成する場合、最初の要求にはクライアント証明書が含まれません。認証 Web サービスは、応答としてクライアント認証を要求します。この応答を受け取ると、Windows クライアントは自動的に証明書ストアを照会して、使用できるクライアント証明書を取得します。ユーザーは、これらの証明書の中から Web サービスへの認証に使うものを選ぶことができます。証明書によってはパスワードで保護されていることがあるので、証明書のパスワードを入力するための手段をユーザーに提供する必要があります。
使用できるクライアント証明書がない場合は、ユーザーが証明書ストアに証明書を追加する必要があります。そこで、クライアント証明書の PFX ファイルをユーザーに選んでもらい、その証明書をクライアント証明書ストアにインポートするコードを Windows ストア アプリに含めることができます。
ヒント makecert.exe を使うと、このクイック スタートで使うことのできる PFX ファイルを作成できます。makecert.exe の使い方について詳しくは、「MakeCert」をご覧ください。
Visual Studio を開き、スタート ページで [新しいプロジェクト] をクリックします。[Visual C#]、[Windows ストア]、[新しいアプリケーション (XAML)] の順に選びます。新しいプロジェクトに "FirstContosoBankApp" という名前を付けます。[OK] をクリックして新しいプロジェクトを作成します。
default.html ファイルで、既定の body 要素に次の HTML を追加します。この HTML には、インポートする PFX ファイルを参照するボタン、PFX ファイルがパスワードで保護されている場合にパスワードを入力するテキスト ボックス、選んだ PFX ファイルをインポートするボタン、セキュリティで保護された Web サービスにログインするボタン、現在の操作の状態を表示するテキスト ブロックが含まれています。
<div> <button id="Browse" style="width:400px;height:80px;font-size:18px">Browse for PFX file</button><br /> PFX password <input id="PfxPassword" type="text" style="width:200px" /> (optional)<br /> <button id="Import" style="width:400px;height:100px;font-size:20px">Import certificate (PFX file)</button><br /> <button id="Login" style="width:400px;height:100px;font-size:20px">Login</button> <div id="Result" style="width:400px;height:400px;color:white" /> </div>
default.html ファイルを保存します。
js フォルダーにある default.js ファイルで、既定の app.onactivated 関数を次の変数と関数に置き換えます。ここでは、"FirstContosoBank" Web サービスのセキュリティで保護された "Login" メソッドのアドレスと、証明書ストアにインポートする PFX 証明書を保持するグローバル変数を指定しています。<server-name> は IIS サーバーの完全修飾名に更新してください。
var pfxPassword; var pfxCert; var requestUri = new Windows.Foundation.Uri("https://<server-name>/FirstContosoBank/Service1.asmx?op=Login"); var result; app.onactivated = function (args) { if (args.detail.kind === activation.ActivationKind.launch) { pfxPassword = document.getElementById("PfxPassword"); result = document.getElementById("Result"); document.getElementById("Import").addEventListener("click", import_click, false); document.getElementById("Login").addEventListener("click", login_click, false); document.getElementById("Browse").addEventListener("click", browse_click, false); args.setPromise(WinJS.UI.processAll()); } };
default.js ファイルで、次に示すように、ログイン ボタンのクリック ハンドラーと、セキュリティで保護された Web サービスにアクセスするためのメソッドを追加します。
function login_click() { makeHttpsCall(); } function makeHttpsCall() { var returnMessage = "Login "; var response; try { var httpClient = new Windows.Web.Http.HttpClient(); httpClient.getAsync(requestUri).then( function (response) { if (response) { if (response.statusCode == Windows.Web.Http.HttpStatusCode.ok) { returnMessage += "successful"; } else { returnMessage += "failed with "; returnMessage += response.StatusCode; } result.innerHTML = returnMessage; } }); } catch (ex) { returnMessage += "failed with "; returnMessage += ex.Message; } result.innerHTML = returnMessage; }
default.js ファイルで、次に示すように、PFX ファイルを参照するボタンのクリック ハンドラーと、選択された PFX ファイルを証明書ストアにインポートするボタンのクリック ハンドラーを追加します。
function import_click() { try { result.innerHTML += "Importing selected certificate into user certificate store....<br />"; var certmgr = Windows.Security.Cryptography.Certificates.CertificateEnrollmentManager.userCertificateEnrollmentManager; certmgr.importPfxDataAsync( pfxCert, pfxPassword.text, Windows.Security.Cryptography.Certificates.ExportOption.exportable, Windows.Security.Cryptography.Certificates.KeyProtectionLevel.noConsent, Windows.Security.Cryptography.Certificates.InstallOptions.deleteExpired, "Import Pfx").then( function () { result.innerHTML += "Certificate import succeded<br />"; }); } catch (ex) { result.innerHTML += "Certificate import failed with " + ex.Message + "<br />"; } } function browse_click() { var resultMessage = "Pfx file selection "; var pfxFilePicker = new Windows.Storage.Pickers.FileOpenPicker(); pfxFilePicker.fileTypeFilter.append(".pfx"); pfxFilePicker.commitButtonText = "Open"; try { pfxFilePicker.pickSingleFileAsync().then( function (pfxFile) { if (pfxFile != null) { Windows.Storage.FileIO.readBufferAsync(pfxFile).then( function (buffer) { var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(buffer); var bytes = new Uint8Array(buffer.length); dataReader.readBytes(bytes); dataReader.close(); pfxCert = btoa(bytes) pfxPassword.text = ""; resultMessage += "succeeded"; }); } else { resultMessage += "failed"; } }); } catch (ex) { resultMessage += "failed with "; resultMessage += ex.Message; } result.innerHTML = resultMessage; }
default.js ファイルを保存します。
これで、F5 キーを押すと Windows ストア アプリが実行されます。セキュリティで保護された Web サービスにログインし、PFX ファイルをローカル証明書ストアにインポートできます。
これらの手順を繰り返すことで、同じユーザー証明書を使ってセキュリティで保護された同じ Web サービスや別の Web サービスにアクセスする複数の Windows ストア アプリを作成できます。
要約
このクイック スタートでは、クライアント証明書によって保護される Web サービスの作成方法と、その保護された Web サービスにアクセスできる Windows ストア アプリの作成方法について説明しました。