了解 ASP.NET AJAX 驗證與設定檔應用程式服務

作者:Scott Cate

驗證服務可讓使用者提供認證以接收驗證 Cookie,而是閘道服務,可允許 ASP.NET 提供的自訂使用者設定檔。 使用 ASP.NET AJAX 驗證服務與標準 ASP.NET 表單驗證相容,因此目前使用表單驗證的應用程式 (,例如透過登入控制項) 升級至 AJAX 驗證服務將不會中斷。

簡介

在 .NET Framework 3.5 中,Microsoft 正在提供可調整大小的環境升級;不僅提供新的開發環境,還即將推出新的 Language-Integrated Query (LINQ) 功能和其他語言增強功能。 此外,其他工具組的一些熟悉功能,特別是 ASP.NET AJAX 擴充功能,會納入為 .NET Framework 基類庫的第一級成員。 這些延伸模組可啟用許多新的豐富用戶端功能,包括部分轉譯頁面,而不需要完整頁面重新整理、透過用戶端腳本存取 Web 服務的能力, (包括 ASP.NET 分析 API) ,以及專為鏡像 ASP.NET 伺服器端控制項集中所見的許多控制項配置而設計的廣泛用戶端 API。

本白皮書會查看 microsoft ASP.NET AJAX 延伸模組公開的 ASP.NET 程式碼剖析和表單驗證服務的實作和使用。AJAX 延伸模組讓表單驗證變得非常容易支援,因為它 (以及程式碼剖析服務) 會透過 Web 服務 Proxy 腳本公開。 AJAX 延伸模組也支援透過 AuthenticationServiceManager 類別進行自訂驗證。

本白皮書是以 Visual Studio 2008 和 .NET Framework 3.5 版的 Beta 2 版本為基礎。 本白皮書也假設您將使用 Visual Studio 2008 Beta 2,而不是 Visual Web Developer Express,並且會根據 Visual Studio 的使用者介面提供逐步解說。 某些程式碼範例可能會利用 Visual Web Developer Express 中無法使用的專案範本。

設定檔和驗證

Microsoft ASP.NET 設定檔和驗證服務是由 ASP.NET 表單驗證系統提供,而且是 ASP.NET 的標準元件。 ASP.NET AJAX 擴充功能可透過腳本 Proxy,透過用戶端 AJAX 程式庫之 Sys.Services 命名空間下的簡單模型,提供這些服務的腳本存取權。

驗證服務可讓使用者提供認證以接收驗證 Cookie,而是閘道服務,可允許 ASP.NET 提供的自訂使用者設定檔。 使用 ASP.NET AJAX 驗證服務與標準 ASP.NET 表單驗證相容,因此目前使用表單驗證的應用程式 (,例如透過登入控制項) 升級至 AJAX 驗證服務將不會中斷。

設定檔服務可根據驗證服務所提供的成員資格,自動整合和儲存使用者資料。 儲存的資料是由web.config檔案所指定,而各種分析服務提供者會處理資料管理。 如同驗證服務,AJAX Profile 服務與標準 ASP.NET 設定檔服務相容,因此目前包含 ASP.NET Profile 服務功能的頁面不應藉由包含 AJAX 支援而中斷。

將 ASP.NET 驗證和分析服務本身併入應用程式,不在此白皮書的範圍內。 如需主題的詳細資訊,請參閱 MSDN Library 參考文章 使用 成員資格管理使用者。 https://msdn.microsoft.com/library/tw292whz.aspx ASP.NET 也包含公用程式,可自動設定具有SQL Server的成員資格,這是 ASP.NET 成員資格的預設驗證服務提供者。 如需詳細資訊,請參閱 ASP.NET SQL Server 註冊工具 (Aspnet_regsql.exe) 一文。 https://msdn.microsoft.com/library/ms229862(vs.80).aspx

使用 ASP.NET AJAX 驗證服務

ASP.NET AJAX 驗證服務必須在web.config檔案中啟用:

<system.web.extensions> 
 <scripting>
 <webServices>
 <authenticationService enabled="true" /> 
 </webServices>
 </scripting> 
</system.web.extensions>

驗證服務需要啟用 ASP.NET 表單驗證,而且需要在用戶端瀏覽器上啟用 Cookie, (腳本無法啟用無 Cookie 會話,因為無 Cookie 會話需要 URL 參數) 。

啟用並設定 AJAX 驗證服務之後,用戶端腳本就可以立即利用 Sys.Services.AuthenticationService 物件。 主要是,用戶端腳本會想要利用 login 方法和 isLoggedIn 屬性。 有數個屬性可用來提供登入方法的預設值,可接受大量的參數。

Sys.Services.AuthenticationService 成員

login 方法:

login () 方法會開始要求驗證使用者的認證。 這個方法是非同步,而且不會封鎖執行。

參數:

參數名稱 意義
userName 必要。 要驗證的使用者名稱。
密碼 選擇性 (預設為 null) 。 使用者的密碼。
isPersistent 選擇性 (預設為 false) 。 使用者驗證 Cookie 是否應該在會話之間保存。 如果為 false,當使用者關閉瀏覽器或會話到期時,將會登出。
redirectUrl 選擇性 (預設為 null) 。在成功驗證時,將瀏覽器重新導向至的 URL。 如果此參數為 null 或空字串,則不會發生重新導向。
customInfo 選擇性 (預設為 null) 。 此參數目前未使用,並保留供日後使用。
loginCompletedCallback 選擇性 (預設為 null) 。登入成功完成時要呼叫的函式。 如果指定,此參數會覆寫 defaultLoginCompleted 屬性。
failedCallback 選擇性 (預設為 null) 。登入失敗時要呼叫的函式。 如果指定,此參數會覆寫 defaultFailedCallback 屬性。
userCoNtext 選擇性 (預設為 null) 。 應該傳遞至回呼函式的自訂使用者內容資料。

傳回值:

此函式不包含傳回值。 不過,完成呼叫此函式時會包含一些行為:

  • 如果 redirectUrl 參數不是 Null 或空字串,則目前的頁面將會重新整理或變更。
  • 不過,如果參數為 null 或空字串,則會 loginCompletedCallback 呼叫 參數或 defaultLoginCompletedCallback 屬性。
  • 如果 Web 服務的呼叫失敗,則會 failedCallback 呼叫 屬性的參數 defaultFailedCallback

logout 方法:

logout () 方法會移除認證 Cookie,並從 Web 應用程式登出目前的使用者。

參數:

參數名稱 意義
redirectUrl 選擇性 (預設為 null) 。在成功驗證時,將瀏覽器重新導向至的 URL。 如果此參數為 null 或空字串,則不會發生重新導向。
logoutCompletedCallback 選擇性 (預設為 null) 。登出成功完成時所要呼叫的函式。 如果指定,此參數會覆寫 defaultLogoutCompleted 屬性。
failedCallback 選擇性 (預設為 null) 。登入失敗時要呼叫的函式。 如果指定,此參數會覆寫 defaultFailedCallback 屬性。
userCoNtext 選擇性 (預設為 null) 。 應該傳遞至回呼函式的自訂使用者內容資料。

傳回值:

此函式不包含傳回值。 不過,完成呼叫此函式時會包含一些行為:

  • 如果 redirectUrl 參數不是 Null 或空字串,則目前的頁面將會重新整理或變更。
  • 不過,如果參數為 null 或空字串,則會 logoutCompletedCallback 呼叫 參數或 defaultLogoutCompletedCallback 屬性。
  • 如果 Web 服務的呼叫失敗,則會 failedCallback 呼叫 屬性的參數 defaultFailedCallback

defaultFailedCallback 屬性 (get,設定) :

這個屬性會指定函式,如果發生與 Web 服務的通訊失敗,應該呼叫此函式。 它應該會收到委派 (或函式參考) 。

此屬性所指定的函式參考應該具有下列簽章:

function AuthenticationFailureCallback(error, userContext, methodName);

參數:

參數名稱 意義
error 指定錯誤資訊。
userCoNtext 指定呼叫登入或登出函式時所提供的使用者內容資訊。
methodName 呼叫方法的名稱。

defaultLoginCompletedCallback 屬性 (get, set) :

這個屬性會指定在登入 Web 服務呼叫完成時應該呼叫的函式。 它應該會收到委派 (或函式參考) 。

這個屬性指定的函式參考應該具有下列簽章:

function AuthenticationLoginCompletedCallback(validCredentials, userContext, methodName);

參數:

參數名稱 意義
validCredentials 指定使用者是否提供有效的認證。 true 如果使用者已成功登入,則為 ;否則為 false
userCoNtext 指定呼叫登入函式時所提供的使用者內容資訊。
methodName 呼叫方法的名稱。

defaultLogoutCompletedCallback 屬性 (get,設定) :

這個屬性會指定當登出 Web 服務呼叫完成時應該呼叫的函式。 它應該會收到委派 (或函式參考) 。

這個屬性指定的函式參考應該具有下列簽章:

function AuthenticationLogoutCompletedCallback(result, userContext, methodName);

參數:

參數名稱 意義
result 此參數一律為 null ;它保留供日後使用。
userCoNtext 指定呼叫登入函式時所提供的使用者內容資訊。
methodName 呼叫方法的名稱。

isLoggedIn 屬性 (取得) :

這個屬性會取得使用者的目前驗證狀態;它會在頁面要求期間由 ScriptManager 物件設定。

如果使用者目前登入,這個屬性會 true 傳回 ,否則會傳 false 回 。

path 屬性 (取得、設定) :

這個屬性會以程式設計方式判斷驗證 Web 服務的位置。 它可以用來覆寫預設驗證提供者,以及在 ScriptManager 控制項的 AuthenticationService 子節點的 Path 屬性中以宣告方式設定的一個集合 (,以取得詳細資訊,如需詳細資訊,請參閱下列使用自訂驗證服務提供者主題) 。

請注意,預設驗證服務的位置不會變更。 不過,ASP.NET AJAX 可讓您指定 Web 服務的位置,以提供與 ASP.NET AJAX 驗證服務 Proxy 相同的類別介面。

另請注意,此屬性不應該設定為將腳本要求導向目前網站的值。 因為目前的應用程式不會收到驗證認證,所以不會用到;此外,基礎 AJAX 的技術不應該張貼跨網站要求,而且可能會在用戶端瀏覽器中產生安全性例外狀況。

這個屬性是物件, String 表示驗證 Web 服務的路徑。

timeout 屬性 (get,設定) :

這個屬性會決定在假設登入要求失敗之前等待驗證服務的時間長度。 如果等候呼叫完成時逾時到期,則會呼叫要求失敗的回呼,而且呼叫不會完成。

這個屬性是 物件, Number 表示等候驗證服務結果的毫秒數。

程式碼範例:登入驗證服務

下列標記是一個範例 ASP.NET 網頁,其中包含 AuthenticationService 類別登入和登出方法的簡單腳本呼叫。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head runat="server">
 <title>Login Example</title>
 <script type="text/javascript">
 function Login()
 {
 var userTextbox = $get("txtUser");
 var passTextbox = $get("txtPassword");
 Sys.Services.AuthenticationService.login(userTextbox.value, 
 passTextbox.value, false, null, null, LoginServiceCompleted, 
 LoginServiceFailed, "Context Info");
 }
 function Logout()
 {
 Sys.Services.AuthenticationService.logout(null, LogoutServiceCompleted, 
 LoginServiceFailed, "Context Info");
 }
 function LoginServiceFailed(error, userContext, methodName)
 {
 alert('There was an error with the authentication service:\n\n' + error);
 }
 function LoginServiceCompleted(validCredentials, userContext, methodName)
 {
 if (validCredentials)
 {
 alert('Great! You successfully logged in.');
 }
 else
 {
 alert('Oops! You gave us bad credentials!');
 }
 }
 function LogoutServiceCompleted(result, userContext, methodName)
 {
 alert('You have been logged out from the web site.');
 }
 </script>
 </head>
 <body>
 <form id="form1" runat="server">
 <asp:ScriptManager ID="ScriptManager1" runat="server" 
 EnableScriptLocalization="true">
 </asp:ScriptManager>
 <div>
 <asp:TextBox ID="txtUser" runat="Server"></asp:TextBox>
 <br />
 <asp:TextBox ID="txtPassword" runat="Server" TextMode="Password"/>
 <br />
 <asp:Button Text="Log in" ID="btnLogin" runat="server" 
 OnClientClick="Login(); return false;" />
 </div>
 </form>
 </body>
</html>

透過 AJAX 存取 ASP.NET 分析資料

ASP.NET 程式碼剖析服務也會透過 AJAX 延伸模組公開 ASP.NET。 由於 ASP.NET 程式碼剖析服務提供豐富的細微 API 來儲存和擷取使用者資料,因此這可以是絕佳的生產力工具。

設定檔服務必須在 web.config 中啟用;它預設不是。 若要這樣做,請確定 profileService 子項目已在 web.config 中指定 enabled= true,而且您已指定哪些屬性可以讀取或寫入,如下所示:

<system.web.extensions>
 <scripting>
 <webServices>
 <profileService enabled="true"
 readAccessProperties= Name,Address,BackgroundColor 
 writeAccessProperties= BackgroundColor />
 </webServices>
 </scripting>
</system.web.extensions>

也必須設定設定檔服務。 雖然分析服務的組態超出此白皮書的範圍,但值得注意的是,設定檔群組態設定中所定義的群組將會以組名的子屬性存取。 例如,指定下列設定檔區段:

<profile enabled="true">
 <properties>
 <add name="Name" type="System.String"/>
 <group name="Address">
 <add name="Line1" type="System.String"/>
 <add name="Line2" type="System.String"/>
 <add name="City" type="System.String"/>
 <add name="State" type="System.String"/>
 <add name="Zip" type="System.String"/>
 </group>
 <add name="BackgroundColor" type="System.Drawing.Color"/>
 </properties>
</profile>

用戶端腳本可以存取 Name、Address.Line1、Address.Line2、Address.City、Address.State、Address.Zip 和 BackgroundColor 做為 ProfileService 類別屬性欄位的屬性。

設定 AJAX 程式碼剖析服務之後,它就會立即在頁面中提供;不過,必須先載入一次,才能使用。

Sys.Services.ProfileService 成員

properties 欄位:

[屬性] 欄位會將所有已設定的設定檔資料公開為可由 dot-operator-name 慣例參考的子屬性。 屬於屬性群組子系的屬性稱為 GroupName.PropertyName。 在上述範例設定檔群組態中,若要取得使用者的狀態,您可以使用下列識別碼:

Sys.Services.ProfileService.properties.Address.State

load 方法:

從伺服器載入選取的清單或所有屬性。

參數:

參數名稱 意義
propertyNames 選擇性 (預設為 null) 。 要從伺服器載入的屬性。
loadCompletedCallback 選擇性 (預設為 null) 。 載入完成時要呼叫的函式。
failedCallback 選擇性 (預設為 null) 。 發生錯誤時要呼叫的函式。
userCoNtext 選擇性 (預設為 null) 。 要傳遞至回呼函式的內容資訊。

load 函式沒有傳回值。 如果呼叫成功完成,它會呼叫 loadCompletedCallback 參數或 defaultLoadCompletedCallback 屬性。 如果呼叫失敗或逾時過期, failedCallback 則會呼叫 參數或 defaultFailedCallback 屬性。

propertyNames如果未提供 參數,則會從伺服器擷取所有讀取設定的屬性。

save 方法:

save () 方法會將指定的屬性清單儲存 (或所有屬性) 至使用者的 ASP.NET 設定檔。

參數:

參數名稱 意義
propertyNames 選擇性 (預設為 null) 。 要儲存至伺服器的屬性。
saveCompletedCallback 選擇性 (預設為 null) 。 儲存完成時要呼叫的函式。
failedCallback 選擇性 (預設為 null) 。 發生錯誤時要呼叫的函式。
userCoNtext 選擇性 (預設為 null) 。 要傳遞至回呼函式的內容資訊。

save 函式沒有傳回值。 如果呼叫成功完成,它會呼叫 saveCompletedCallback 參數或 defaultSaveCompletedCallback 屬性。 如果呼叫失敗,或逾時已過期, failedCallback 則會呼叫 或 defaultFailedCallback 屬性。

propertyNames如果參數為 Null,所有配置檔案屬性都會傳送至伺服器,而伺服器會決定可以儲存哪些屬性,以及哪些屬性無法儲存。

defaultFailedCallback 屬性 (get,設定) :

這個屬性會指定函式,如果發生與 Web 服務的通訊失敗,應該呼叫此函式。 它應該會收到委派 (或函式參考) 。

這個屬性指定的函式參考應該具有下列簽章:

function AuthenticationFailureCallback(error, userContext, methodName);

參數:

參數名稱 意義
錯誤 指定錯誤資訊。
userCoNtext 指定呼叫載入或儲存函式時所提供的使用者內容資訊。
methodName 呼叫方法的名稱。

defaultSaveCompleted 屬性 (get,設定) :

這個屬性會指定在儲存使用者設定檔資料完成時應該呼叫的函式。 它應該會收到委派 (或函式參考) 。

這個屬性指定的函式參考應該具有下列簽章:

function ProfileSaveComplete(numPropsSaved, userContext, methodName);

參數:

參數名稱 意義
numPropsSaved 指定已儲存的屬性數目。
userCoNtext 指定呼叫載入或儲存函式時所提供的使用者內容資訊。
methodName 呼叫方法的名稱。

defaultLoadCompleted 屬性 (get、設定) :

這個屬性會指定在載入使用者設定檔資料時應該呼叫的函式。 它應該會收到委派 (或函式參考) 。

這個屬性指定的函式參考應該具有下列簽章:

function ProfileLoadComplete(numPropsLoaded, userContext, methodName);

參數:

參數名稱 意義
numPropsLoaded 指定載入的屬性數目。
userCoNtext 指定呼叫載入或儲存函式時所提供的使用者內容資訊。
methodName 呼叫方法的名稱。

path 屬性 (取得、設定) :

這個屬性會以程式設計方式判斷設定檔 Web 服務的位置。 它可以用來覆寫預設設定檔服務提供者,以及在 ScriptManager 控制項的 ProfileService 子節點的 Path 屬性中以宣告方式設定。

請注意,預設設定檔服務的位置不會變更。 不過,ASP.NET AJAX 可讓您指定 Web 服務的位置,以提供與 ASP.NET AJAX 驗證服務 Proxy 相同的類別介面。

另請注意,此屬性不應該設定為將腳本要求導向目前網站的值。 基礎 AJAX 的技術不應該張貼跨網站要求,而且可能會在用戶端瀏覽器中產生安全性例外狀況。

這個屬性是物件, String 代表設定檔 Web 服務的路徑。

timeout 屬性 (get,設定) :

此屬性會決定在假設載入或儲存要求失敗之前等待設定檔服務的時間長度。 如果等候呼叫完成時逾時到期,則會呼叫要求失敗的回呼,而且呼叫不會完成。

這個屬性是 物件, Number 表示等候設定檔服務結果的毫秒數。

程式碼範例:在頁面載入時載入設定檔資料

下列程式碼會檢查使用者是否已通過驗證,如果是,則會將使用者的慣用背景色彩載入為頁面的 。

function Page_Load()
{
 if (Sys.Services.AuthenticationService.get_isLoggedIn())
 {
 Sys.Services.ProfileService.load();
 }
}
function ProfileLoaded(numPropsLoaded, userContext, methodName)
{
 document.documentElement.style.backgroundColor = Sys.Services.ProfileService.properties.BackgroundColor;
}

使用自訂驗證服務提供者

ASP.NET AJAX 延伸模組可讓您透過自訂 Web 服務公開功能來建立自訂腳本驗證服務提供者。 若要使用,您的 Web 服務必須公開兩種方法, LoginLogout 而且這些方法必須以與預設 ASP.NET AJAX 驗證 Web 服務相同的方法簽章來指定。

建立自訂 Web 服務之後,您必須以宣告方式在頁面上指定路徑、以程式設計方式在程式碼中,或透過用戶端腳本指定路徑。

若要以宣告方式設定路徑:

若要以宣告方式設定路徑,請在 ASP.NET 網頁上包含 ScriptManager 物件的 AuthenticationService 子系:

<asp:ScriptManager ID="ScriptManager1" runat="server">
 <AuthenticationService Path="~/AuthService.asmx" />
</asp:ScriptManager>

若要在程式碼中設定路徑:

若要以程式設計方式設定路徑,請透過腳本管理員的實例指定路徑:

protected void Page_Load(object sender, EventArgs e)
{
    this.ScriptManager1.AuthenticationService.Path = "~/AuthService.asmx";
}

若要在腳本中設定路徑:

若要以程式設計方式在腳本中設定路徑,請使用 path AuthenticationService 類別的 屬性:

function Login()
{
 var userTextbox = $get("txtUser");
 var passTextbox = $get("txtPassword");
 Sys.Services.AuthenticationService.set_path("./AuthService.asmx");
 Sys.Services.AuthenticationService.login(userTextbox.value, passTextbox.value, false, null, null, LoginServiceCompleted, LoginServiceFailed, "Context Info");
}

自訂驗證的範例 Web 服務

<%@ WebService Language="C#" Class="AuthService" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
[ScriptService]
[WebService]
public class AuthService : WebService
{
 [WebMethod]
 public bool Login(string userName, string password, bool createCookie)
 {
 Session["LoggedInUser"] = userName;
 return true;
 }
 [WebMethod]
 public void Logout()
 {
 Session.Abandon();
 }
}

總結

ASP.NET 服務-特別是分析、成員資格和驗證服務 - 可以輕鬆地在用戶端瀏覽器中公開至 JavaScript。 這可讓開發人員順暢地整合其用戶端程式代碼與驗證機制,而不需依賴 UpdatePanels 之類的控制項來執行繁重的工作。 設定檔資料也可以透過使用 Web 組態設定來保護用戶端;預設沒有可用的資料,開發人員必須加入宣告配置檔案屬性。

此外,藉由建立具有對等方法簽章的簡化 Web 服務實作,開發人員可以針對這些內建 ASP.NET 服務建立自訂腳本提供者。 支援這些技術可簡化豐富用戶端應用程式的開發,同時為開發人員提供各種彈性以符合特定需求。

簡歷

Scott Cate 自 1997 年以來一直與 Microsoft Web 技術合作,而且是 myKB.com (www.myKB.com) ,他專門撰寫著重于知識庫軟體解決方案的 ASP.NET 型應用程式。 Scott 可以透過電子郵件 scott.cate@myKB.com 或其部落格連絡,網址為 ScottCate.com