Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
SharePoint 2010 向けカスタム ログイン ページの作成 パート 1
SharePoint 2007 では、フォーム ベース認証 (FBA) 用のカスタム ログイン ページの作成がそれほど困難ではありませんでした。 いくつか理解しておくことはありましたが、そのほとんどは SharePoint 特有のものではなく、なかには標準的な SharePoint レイアウト ページの外観をログイン フォームに持たせるためのヒントもありました。 とにかく、ASP.NET と FormsAuthentication クラスについて理解していれば問題なかったのです。 ところが幸か不幸か、SharePoint 2010 では事態がもう少し複雑になっています。
ここでは、カスタム ログイン ページのあるシナリオについて説明します。 この例では、完全にカスタムのログイン ページが要求されます。外観の変更だけでは済まないので、まったく別の UI が必要になります。 たとえば、ログインに使用するメンバーシップ資格情報の取得が必要なことがあります。また、SecureID の場合のように、セカンダリ認証 ID の入力が必要になることもあります。 こうした場合は、ユーザー名とパスサードを入力するための 2 つのテキスト ボックスを ASP.NET ページに用意し、それらを取得してプログラムによってユーザーのログイン処理を行う必要があります。
ここで注意すべき重要な点は、これまで使用してきた FormsAuthentication クラスが不要になることです。 SharePoint 2010 では FBA ユーザーが実際にクレーム ユーザーであることがその理由です。 つまり、標準の ASP.NET メンバーシップ ユーザーとロール プロバイダーを使用して作業する場合でも、内部ではこれらのオブジェクトがクレーム認証用のシェルを持つことになります。 そのため、FBA ログイン処理では SharePoint クレーム クラスのいくつかを使用する必要があります。
ここで 1 つ注意事項があります。 通常は何らかの形で、ブログにコンテンツを投稿する前に、できる限りの調査や検証をだれかの協力を得て行います。これが何かを行う場合の正当かつ適切で支持される方法です。 今回説明する方法についても検証を何度も試みたのですが、実際にはできませんでした。 紹介するコードは、私が取り組んでいるプロジェクトで使用して正しく動作することを確認したものですが、何らかの変更を加えれば同じ作業をもっと適切な形で実行できることが後で明らかになる可能性があります。その点はご了承ください。 言い訳はこれくらいにして、コードの説明に移ります。
最初に、後で必要になる 2 つの参照を紹介しておきます。おそらく、読者のみなさんがこれまで使用したことのないものです。 1 つは、ISAPI フォルダーの 14 ハイブにある Microsoft.SharePoint.Security.dll です。 もう 1 つは慎重に使う必要があるもので、先ほどの注意事項はこれに起因しています。 それが Microsoft.SharePoint.IdentityModel.dll への参照です。 ただし、参照を追加しようとしても、このアセンブリは容易には見つかりせん。私のソースがあまり洗練されておらず、また用心深いものになっているのはそのためです。 一番良い方法は、別の投稿でも説明しているように、ファイル システム上で検索してわかりやすい場所にコピーし、コピーしたバージョンへの参照を追加することです。 通常、私がこうした検索を行うときは、コマンド プロンプトを開き、ドライブのルートに移動して、"dir Microsoft.SharePoint.IdentityModel.dll /s" を実行します。 この作業が完了したら、以下に示す using ステートメント群を追加します。
using System.Web.Security;
using System.IdentityModel.Tokens;
using Microsoft.SharePoint;
using Microsoft.SharePoint.IdentityModel;
ややこしい前置きはこれくらいにして本題に入ります。クレーム クラスを呼び出してユーザーが入力した FBA ユーザー資格情報を検証する場合は、そのクラスが使用するメンバーシップおよびロール プロバイダーを指定する必要があります。 必要なのは名前だけです。 この例では自分の作業用にカスタムのメンバーシップおよびロール プロバイダーを作成していたので、目的のものが見つかるまで Web アプリケーション側で把握しているすべてのプロバイダーを順に処理しています。
//get the provider names for our type
string userProviderName = string.Empty;
string roleProviderName = string.Empty;
//get the membership provider name
foreach (MembershipProvider p in Membership.Providers)
{
if (p.GetType().Equals(typeof(Microsoft.SE.AnonProvider.Users)))
{
userProviderName = p.Name;
break;
}
}
//get the role provider name
foreach (RoleProvider rp in System.Web.Security.Roles.Providers)
{
if (rp.GetType().Equals(typeof(Microsoft.SE.AnonProvider.Roles)))
{
roleProviderName = rp.Name;
break;
}
}
これでプロバイダーの名前を取得できました。 今度は、ユーザー名とパスワードを取得し、セキュリティ トークンを返す必要があります。 そのためには SPSecurityContext クラスを使用します。 このクラスには、まさにこうしたフォーム ベースの認証によるログインを実行するためのメソッドが用意されており、認証に成功した場合はセキュリティ トークン、失敗した場合は NULL が返されます。 以下に、ユーザー資格情報の認証を行うコードを示します。
SecurityToken tk = SPSecurityContext.SecurityTokenForFormsAuthentication(
new Uri(SPContext.Current.Web.Url), userProviderName, roleProviderName,
UserNameTxt.Text, PasswordTxt.Text);
ここでは、認証を受けようとするサイトの URI を渡し、自分のメンバーシップおよびロール プロバイダーを指定して、ログイン ページのテキスト ボックスに入力されたユーザー名とパスワードの値を渡しています。 続いて、SecurityToken が NULL でないかどうかを確認し、NULL でない場合はセッション トークンを作成する必要があります。 この処理は SPFederationAuthenticationModule によって行います。 セッション トークンを作成することで、処理をさらに進めて、要求された任意のページまたはリソースにユーザーをリダイレクトできるようになります。 以下に、この処理を実行するための残りのコードを示します。
if (tk != null)
{
//try setting the authentication cookie
SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
fam.SetPrincipalAndWriteSessionToken(tk);
//look for the Source query string parameter and use that as the redirection
string src = Request.QueryString["Source"];
if (!string.IsNullOrEmpty(src))
Response.Redirect(src);
}
else
{
StatusLbl.Text = "The credentials weren't valid or didn't work or something.";
}
これで、何も問題がなければ、ソースのクエリ文字列パラメーターが得られることがわかります。このパラメーターによって、ユーザーが当初目指していた場所がわかります。 あとはユーザーを各自の行き先にリダイレクトするだけです。
この投稿が読者のみなさんの参考になれば幸いです。 こうした処理を行う最適な方法に関するドキュメントは、私が探したときにはなかなか見つかりませんでした。 パート 2 では、別のシナリオでこうした処理を実行する方法を紹介します。 具体的には、サイトを初めて使用する前に "この Web サイトの使用条件に同意します" といった確認を求めるような場合です。 そのために、基本のログイン ページを拡張し、ログイン時にハンドラーを追加する方法を説明します。
これはローカライズされたブログ投稿です。原文の記事は「Writing A Custom Forms Login Page for SharePoint 2010 Part 1」をご覧ください。