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 自訂表單登入頁面 (第一部分)
在 SharePoint 2007,撰寫表單型驗證 (FBA) 網站的自訂登入頁面並不是十分困難。 您必須具備一些基本概念 (大部分與 SharePoint 無關),還要知道一些訣竅,才能讓登入表單有 SharePoint 版面配置的外觀與感受。 不過,整體而言,如果熟悉 ASP.NET 及 FormsAuthentication 類別,就已經足夠。 不幸的是,SharePoint 2010 變得比較複雜。
本文將以一個案例來說明自訂登入頁面。 在本範例中,我們需要的是一個完全自訂的登入頁面 - 不單只是變更外觀與感受,而是一個全然不同的使用者介面。 舉例來說,我們可能需要擷取登入時所用的成員資格認證,可能也需要使用者輸入次要驗證識別碼,譬如次要驗證識別碼可能是 SecurID 識別碼。 因此,我們會在 ASP.NET 頁面上設計幾個文字方塊,讓使用者輸入使用者名稱及密碼,再利用這些資訊,透過程式讓他們登入。
最重要的是,本範例不再使用大家熟知的 FormsAuthentication 類別。 這是因為在 SharePoint 2010,表單型驗證使用者其實就是宣告驗證使用者。 因此,表面上,您可能認為使用的是標準 ASP.NET 成員資格使用者及角色提供者,實際上,這些物件都具備令人驚艷的宣告驗證殼層。 有鑑於此,必須使用一些 SharePoint 宣告類別,才能進行整個表單型驗證登入程序。
但我必須在這裡鄭重提醒: 通常,無論在什麼情況下,我都會在發表文章之前,事前研究一番,或儘可能徹底驗證別人的說法是否正確。 這次,我也一直試著檢查整個作法是否無誤,不過沒辦到。 我把這個程式碼放在過去開發的專案上,結果是可行的,不過,要是日後程式監督人員通知您得修改程式,採用其他更好更適當的作法時,可千萬別停止心跳。 說完明哲保身的托詞後,來看看部分程式碼吧。
開始之前,需要用到一些參考,這些您可能從來沒用過。 第一個是 Microsoft.SharePoint.Security.dll,這個檔案位於 ISAPI 資料夾的 14 登錄區。 另外一個,比較麻煩,這就是我之所以在前面鄭重提醒您的原因, 因為您必須參考 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;
現在處理完這件有點麻煩的事之後,當我呼叫宣告類別來驗證使用者在表單型驗證中輸入的認證時,我必須讓驗證作業知道應該使用哪個成員資格及角色提供者。 它只要知道名稱就行了。 我曾經有一個特殊案子,其中使用自訂的成員資格及角色提供者,我的作法是列舉出我的 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;
}
}
這樣就找到提供者名稱了。 現在,我們要用使用者名稱及密碼傳回 SecurityToken, 所以,得使用 SPSecurityContext 類別。 這個類別有個方法可以自動輸入表單型驗證登入;如果執行成功,就會傳回 SecurityToken,否則就會傳回 Null。 下面是驗證使用者的程式碼:
SecurityToken tk = SPSecurityContext.SecurityTokenForFormsAuthentication(
new Uri(SPContext.Current.Web.Url), userProviderName, roleProviderName,
UserNameTxt.Text, PasswordTxt.Text);
所以,我傳遞了比對驗證的網站 URI,也提供了成員資格及角色提供者名稱,現在要傳遞登入頁面中輸入的使用者名稱及密碼值。 所以我必須檢查 SecurityToken 確認不是 Null;如果不是的話,就要撰寫工作階段 Token。 這必須用到 SPFederationAuthenticationModule。 完成工作階段 Token 之後,接著就可以將使用者重新導向他們要求的頁面或資源。 下面就是執行這項工作的其餘程式碼:
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.";
}
現在,所有動作都順利完成,接下來我只要再使用 Source 查詢字串參數,就可以知道原本使用者所要求的位置。 得到這個位置資料後,即可讓使用者前往該位置。
希望這篇文章能幫助您順利進行登入頁面的設計工作。 當初我也曾大費周章想找找最佳作法來參考,所以我知道真的不容易找到相關資料。 在第二部分,我將針對另一個不同案例,以不同作法,來開發這個登入頁面。 在這個頁面,我們會要求使用者在第一次進入網站時,選擇「我同意接受此網站的使用條款」, 因此,在作法上,將會延伸基礎登入頁面,並在登入時加入處理常式。
這是翻譯後的部落格文章。英文原文請參閱 Writing A Custom Forms Login Page for SharePoint 2010 Part 1