【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 アプリケーション」でよいでしょう。

image

プロジェクトが開いたら、前回作成したライブラリ(IdentityModel.WP7.dll)を「参照設定」に追加します。

image

MainPage.xaml ファイルをダブルクリックして開いてください。ここに、ボタンを2つ追加しておきます。1つは SSL 証明書をインストールするためのボタン、もう1つはログオンしてセキュリティトークンを受け取るためのボタンです。今回は極力シンプルにするためにユーザー名やパスワードなどは、すべてハードコーディングしてしまいます。なのでテキストボックスは使いません。

image

はじめに、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 と証明書の関係については、以下の投稿をご覧ください。

【WP for ITPro】Windows Phone とルート証明書の関係、自己署名証明書のインストール方法

ここまでできたら、ためしに実行してみます。F5 キーを押して実行してください。「証明書をインストールする」をタップすると、以下の画面が表示されますか?表示されていない場合には、証明書のパスが異なるか、証明書が p7b 形式ではありません。

imageimageimage

ちなみに、ここで使用している WebBrowserTask は、WEBサイトからドキュメントをダウンロードして開くときなんかにも使える便利な手法ですので、覚えておきましょう。

OK ならばセキュリティトークンを取得するコードを書きましょう。

まずは、参照設定で System.ServiceModel を追加してください。これは、コードの中で EndpointAddress クラスを使用するためです。

imageimage

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サーバーのこと)が見つからない旨のエラーが表示されてしまうので注意してください。

以下のような画面が表示されましたか?

image

少しスクロールすると、ADFSで設定したクレームの内容が含まれていることがわかります。

image

サンプルプロジェクトおよび AD FS の設定方法等については、2011/11/28 セミナー資料 Windows Phone アプリケーションに認証機能を実装する に掲載してありますので、参考にしてください。

以上完結です。