【WP for ITPro】Windows Phone から直接 Active Directory 認証を行うには ~その4(完結編)
※この投稿は Windows Phone Advent Calender 2011 に参加しています
※こちらもお勧め Windows Phone Advent Calendar "ひとり" 2011 : ATND
Windows Phone + Active Directory の 4 回目です。過去の投稿は以下より。
2011年11月28日 Tech Fielders セミナー 「Windows Phone に認証機能を実装する」で使用した資料、ソースコードは以下からどうぞ。当日の収録動画もあります。 2011/11/28 セミナー資料 Windows Phone アプリケーションに認証機能を実装する |
前回までの作業で準備が整いました(かなり時間が空いてしまいましたが)。ここからは、実際に Active Directory Federation Service からセキュリティトークンを受け取ってみましょう。
極力シンプルなコードにするために、各パラメタはハードコーディングしますのでご容赦ください。
はじめに新しい Windows Phone のプロジェクトを作成します。選択するテンプレートは「Windows Phone アプリケーション」でよいでしょう。
プロジェクトが開いたら、前回作成したライブラリ(IdentityModel.WP7.dll)を「参照設定」に追加します。
MainPage.xaml ファイルをダブルクリックして開いてください。ここに、ボタンを2つ追加しておきます。1つは SSL 証明書をインストールするためのボタン、もう1つはログオンしてセキュリティトークンを受け取るためのボタンです。今回は極力シンプルにするためにユーザー名やパスワードなどは、すべてハードコーディングしてしまいます。なのでテキストボックスは使いません。
はじめに、AD FS の SSL 証明書をインストールするための仕組みを実装します。
「証明書をインストールする」ボタンをダブルクリックしてください。ボタン名が button1 の場合には以下の黄色いマーカーで塗った部分が表示されるはずです。ここに、以下の太字部分を追加してください。using 句で Microsoft.Phone.Tasks を追記するのも忘れないようにしましょう。
MainPage.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Phone.Tasks; namespace PhoneApp1 { public partial class MainPage : PhoneApplicationPage { // コンストラクター public MainPage() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { string CertP7BPath = " https://tfdc01.tf.com/adfs.p7b"; WebBrowserTask webBrowserTask = new WebBrowserTask(); webBrowserTask.Uri = new Uri(CertP7BPath, UriKind.Absolute); webBrowserTask.Show(); } } } |
CertP7BPath には、ADFS のサーバー証明書を公開している URL を指定してください。ここでは Webブラウザタスクを呼び出しているため、インストール可能な形式は .p7b です。Windows Phone と証明書の関係については、以下の投稿をご覧ください。
ここまでできたら、ためしに実行してみます。F5 キーを押して実行してください。「証明書をインストールする」をタップすると、以下の画面が表示されますか?表示されていない場合には、証明書のパスが異なるか、証明書が p7b 形式ではありません。
ちなみに、ここで使用している WebBrowserTask は、WEBサイトからドキュメントをダウンロードして開くときなんかにも使える便利な手法ですので、覚えておきましょう。
OK ならばセキュリティトークンを取得するコードを書きましょう。
まずは、参照設定で System.ServiceModel を追加してください。これは、コードの中で EndpointAddress クラスを使用するためです。
MainPage.xaml を開いて、「セキュリティトークンを取得」ボタンをダブルクリックしてください。以下のように button2_Click イベントハンドラが追加されます。ここに、セキュリティトークンを取得するためのコードを書きこんでいきます。
はじめに、using 句で、冒頭で参照設定したライブラリの名前空間(SL.IdentityModel.Claims、SL.IdentityModel.Protocols.WSTrust)と、System.ServiceModel を追記しておきます。
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Phone.Tasks; using SL.IdentityModel.Claims; using SL.IdentityModel.Protocols.WSTrust; using System.ServiceModel; namespace PhoneApp1 { public partial class MainPage : PhoneApplicationPage { // コンストラクター public MainPage() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { string CertP7BPath = "https://tfdc01.tf.com/adfs.p7b"; WebBrowserTask webBrowserTask = new WebBrowserTask(); webBrowserTask.Uri = new Uri(CertP7BPath, UriKind.Absolute); webBrowserTask.Show(); } private void button2_Click(object sender, RoutedEventArgs e) { ここにコードを追記する } } } |
button2_Click イベントハンドラに以下のようなコードを追記し、さらに client_IssueCompleted も追記します。セキュリティトークンの取得は非同期で行われるため、_client.IssueAsync の呼び出しから応答が戻るのを、client_IssueCompleted で待ち合わせているわけですね。
WSTrustClient _client; がイベントハンドラの外に飛び出していますが、これは他の関数でも使用するためです。場所的にお行儀が悪いですが、ここではよしとしてください。
WSTrustClient _client; private void button2_Click(object sender, RoutedEventArgs e) { string EndPoint_WSTrust = "https://tfadfs.tf.com/adfs/services/trust/13/usernamemixed"; string EndPoint_RP = "https://www.junichia.com/"; string UserName = "tf\\administrator"; string Password = "P@ssw0rd"; _client = new WSTrustClient( new WSTrustBindingUsernameMixed(), new EndpointAddress(EndPoint_WSTrust), new UsernameCredentials(UserName, Password)); var rst = new RequestSecurityToken(WSTrust13Constants.KeyTypes.Bearer) { AppliesTo = new EndpointAddress(EndPoint_RP) }; _client.IssueCompleted += client_IssueCompleted; _client.IssueAsync(rst); } void client_IssueCompleted(object sender, IssueCompletedEventArgs e) { _client.IssueCompleted -= client_IssueCompleted; if (e.Error == null) { MessageBox.Show(e.Result.RequestedSecurityToken.RawToken.ToString()); } else { MessageBox.Show(e.Error.Message); } } |
コードはたったこれだけです。これだけでADFSからセキュリティトークンを受け取ることができます。
なお、以下の4つの変数には、それぞれユーザー環境での値を入力してください。
- string EndPoint_WSTrust = "https://<ADFSサーバー名>/adfs/services/trust/13/usernamemixed";
- string EndPoint_RP = "<ADFSの管理コンソールに追加した証明書利用者信頼>";
- string UserName = "<ドメイン名>\\<ユーザー名>";
- string Password = "<パスワード>";
UserName に指定する<ドメイン名>と<ユーザー名>の間には2つのエンサイン(\\)が入るので注意しましょう。エンサイン1つだけでは特殊文字として認識されてしまいます。
実際に実行してみましょう。
実行結果はメッセージボックスに表示されるようにしています。
はじめに証明書のインストールを行わないと、Issure (ADFSサーバーのこと)が見つからない旨のエラーが表示されてしまうので注意してください。
以下のような画面が表示されましたか?
少しスクロールすると、ADFSで設定したクレームの内容が含まれていることがわかります。
サンプルプロジェクトおよび AD FS の設定方法等については、2011/11/28 セミナー資料 Windows Phone アプリケーションに認証機能を実装する に掲載してありますので、参考にしてください。
以上完結です。