SharePoint 2010 で複数の認証プロバイダーの選択ページをバイパスする
原文の記事の投稿日: 2011 年 5 月 1 日 (日曜日)
余談: このサイトを運営しているすばらしい方々に、称賛の意を表します。この最新版では、これまで以上に、Word や Visual Studio さえも下回る書式が使用されています。このサイトをこれまでよりひどいものにすることが可能だとは思いもしませんでした。さんざんではありますが、はっきり言って、この点に関する期待は吹き飛びました。おめでとうございます! 私もこれを見習い、Word、Excel、PowerPoint は止めてメモ帳にします。どうせ、書式を設定する必要などないですから。
最近、私は、SharePoint 2010 内の 1 つのゾーンで複数の認証プロバイダーが有効な場合に、プロバイダーの選択ページをバイパスする必要がありました。私が経験したシナリオは非常に単純なものでしたが、その方法を大幅に拡張することで、より複雑なシナリオをサポートできます。私のケースでは、ゾーンで Windows 認証とフォーム ベース認証 (FBA) が有効でした。しかし、この特定のシナリオでは、常に FBA を使用するようにユーザーをリダイレクトする必要がありました。
次の手順により、これは比較的簡単に実行できました。
- C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IDENTITYMODEL\LOGIN フォルダー内の default.aspx のバックアップ コピーを作成します。
- Visual Studio を開き、新しい Windows クラス ライブラリ プロジェクトを作成します。
- System.Web、Microsoft.SharePoint.dll、および Microsoft.SharePoint.IdentityModel.dll への参照を追加します。残念ながら、ID モデル アセンブリは GAC 内にのみあるので、そのコピーを取得し、それを自分のドライブのルートに配置して、参照を追加する必要がありました。その検索とコピーの方法については、私の次の投稿を参照してください。https://blogs.msdn.com/b/sharepoint_jp/archive/2010/11/26/sharepoint-2010-1.aspx
- GAC に配置されることになるので、アセンブリに厳密な名前を指定します。
- プロジェクトに新しい ASPX ページを追加します。実際のところ、既存の ASP.NET Web アプリケーション プロジェクトからページをコピーするのが最も簡単です。この方法であれば、.aspx、.aspx.cs、および .aspx.designer.cs ファイルをまとめてコピーできます。このケースでは、必要なファイルは “default.aspx” であり、コードがまだ記述されておらず、ページ内のマークアップは最小限である方が簡単です。
- 分離コード (.aspx.cs ファイル) で、現在のプロジェクトの名前空間に一致するように、名前空間を変更します。
- Microsoft.SharePoint.IdentityModel.Pages.MultiLogonPage から継承するように、クラスを変更します。
- OnLoad イベントを上書きします。複数の認証プロバイダーが有効化されているサイトにユーザーがアクセスすると、ユーザーは、最初、/_login/default.aspx ページ (上記の手順 1. に記載のページ) に送られます。そのページでユーザーは使用する認証プロバイダーを選択し、適切なページにリダイレクトされて認証が行われます。このシナリオでは、前述のように、ユーザーは常に FBA で認証する必要があるため、ユーザーを常に /_forms/default.aspx に送る必要があります。通常のログインの手順では、/_login/default.aspx にリダイレクトされ、選択を行うと、/_login/default.aspx にポストバックされ、適切なログイン ページにリダイレクトされます。そこで、このケースでは、ログイン ページがポストバックされているかどうかだけに注目しました。ポストバックされていなければ、認証プロバイダーの選択がまだ行われていないということです。そこで、すべてのクエリ文字列値を列挙してそれらを /_forms/default.aspx に追加し、ユーザーをそこにリダイレクトします。コード スニペット全体は次のようになります。
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
try
{
//if this isn't a postback, then the user hasn't selected which
//auth provider they want to use
//in this case we want to always refer the person to forms login
if (!this.IsPostBack)
{
//grab all the query string parameters
System.Text.StringBuilder qp = new System.Text.StringBuilder(2048);
foreach (string key in this.Request.QueryString.Keys)
{
qp.Append(key + "=" + this.Request.QueryString[key] + "&");
}
//redirect to the forms login page
this.Response.Redirect("/_forms/default.aspx?" + qp.ToString());
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
- アプリケーションをコンパイルすると、その厳密な名前を取得し、それを default.aspx のマークアップに追加できます。
- 以下を default.aspx に貼り付けます。ページの継承元のクラスのみ、変更する必要があります (以下で強調表示されている箇所)。これは、/_login/default.aspx からコピーして、Inherits 値を自分のカスタム クラス情報に置き換えただけのものです。
<%@ Page Language="C#" CodeBehind="Default.aspx.cs" Inherits="MultiAuthLoginPage._Default,MultiAuthLoginPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=907bf41ebba93579" MasterPageFile="~/_layouts/simple.master" %>
<%@ Assembly Name="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharepointIdentity" Namespace="Microsoft.SharePoint.IdentityModel" Assembly="Microsoft.SharePoint.IdentityModel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Import Namespace="Microsoft.SharePoint.WebControls" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" Id="ClaimsLogonPageTitle" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" Id="ClaimsLogonPageTitleInTitleArea" />
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderId="PlaceHolderSiteName" runat="server"/>
<asp:Content ID="Content4" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<SharePoint:EncodedLiteral runat="server" EncodeMethod="HtmlEncode" Id="ClaimsLogonPageMessage" />
<br />
<br />
<SharepointIdentity:LogonSelector ID="ClaimsLogonSelector" runat="server" />
</asp:Content>
- アセンブリを GAC に登録します。
- 新しいカスタムの default.aspx ページを、C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IDENTITYMODEL\LOGIN フォルダーにコピーします。この操作の前に、オリジナルのバックアップを必ず作成してください。
- ファーム内のすべての Web フロント エンドについて、手順 1.、11.、および 12. を実行します。
たったこれだけです。これを標準のユーザー ログインでテストし、Microsoft Office 2010 クライアントから直接ドキュメントも開いてみました。ここで注目すべきもう 1 つの点は、これによって、ファーム内のすべての Web アプリケーションの動作が変わるということです。だからこそ、これは単純な例です。しかし、要求 (Web アプリケーションへマップされる) のホスト名は簡単に調べることができ、アクセスされる Web アプリケーションや、場合によってはサイト コレクションに基づいて、異なる認証の決定を行うことができます。現在のユーザーに関する情報に基づいて他の決定を行うことも、もちろん可能です。HttpRequest.Context.Current、Page.Request、Page.Response の各クラスは、このような決定を行うための多くの情報を提供します。
これはローカライズされたブログ投稿です。原文の記事は、「Bypassing the Multi Authentication Provider Selection Page in SharePoint 2010」をご覧ください。