了解 ASP.NET AJAX 身份验证和配置文件应用程序服务

作者 :Scott Cate

身份验证服务允许用户提供凭据以接收身份验证 Cookie,是允许 ASP.NET 提供的自定义用户配置文件的网关服务。 使用 ASP.NET AJAX 身份验证服务与标准 ASP.NET Forms 身份验证兼容,因此当前使用 Forms 身份验证 (的应用程序(例如登录控件) )不会因升级到 AJAX 身份验证服务而中断。

简介

作为.NET Framework 3.5 的一部分,Microsoft 正在提供一个相当大的环境升级;不仅提供了新的开发环境,而且还将推出新的Language-Integrated查询 (LINQ) 功能和其他语言增强功能。 此外,其他工具集的一些熟悉功能(尤其是 ASP.NET AJAX 扩展)作为.NET Framework基类库的一流成员包含在内。 这些扩展支持许多新的丰富客户端功能,包括无需完整页面刷新的部分呈现页面、通过客户端脚本访问 Web 服务的功能 (包括 ASP.NET 分析 API) ,以及旨在镜像 ASP.NET 服务器端控件集中的许多控制方案的广泛客户端 API。

本白皮书介绍 microsoft ASP.NET AJAX 扩展公开的 ASP.NET 事件探查和表单身份验证服务的实现和使用。AJAX 扩展使表单身份验证非常易于支持,因为它 (以及分析服务) 通过 Web 服务代理脚本公开。 AJAX 扩展还支持通过 AuthenticationServiceManager 类进行自定义身份验证。

本白皮书基于 Visual Studio 2008 的 Beta 版 2 和 .NET Framework 3.5。 本白皮书还假定你将使用 Visual Studio 2008 Beta 2,而不是 Visual Web Developer Express,并将根据 Visual Studio 的用户界面提供演练。 某些代码示例可能利用 Visual Web Developer Express 中不可用的项目模板。

配置文件和身份验证

Microsoft ASP.NET 配置文件和身份验证服务由 ASP.NET Forms 身份验证系统提供,是 ASP.NET 的标准组件。 ASP.NET AJAX 扩展通过脚本代理通过客户端 AJAX 库的 Sys.Services 命名空间下的一个相当简单的模型提供对这些服务的脚本访问。

身份验证服务允许用户提供凭据以接收身份验证 Cookie,是允许 ASP.NET 提供的自定义用户配置文件的网关服务。 使用 ASP.NET AJAX 身份验证服务与标准 ASP.NET Forms 身份验证兼容,因此当前使用 Forms 身份验证 (的应用程序(例如登录控件) )不会因升级到 AJAX 身份验证服务而中断。

配置文件服务允许根据身份验证服务提供的成员身份自动集成和存储用户数据。 存储的数据由 web.config 文件指定,各种分析服务提供程序处理数据管理。 与身份验证服务一样,AJAX 配置文件服务与标准 ASP.NET 配置文件服务兼容,因此当前包含 ASP.NET 配置文件服务功能的页面不应因包含 AJAX 支持而中断。

将 ASP.NET 身份验证和分析服务本身合并到应用程序中超出了本白皮书的范围。 有关主题的详细信息,请参阅 上的 https://msdn.microsoft.com/library/tw292whz.aspxMSDN 库参考文章使用成员身份管理用户。 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 身份验证服务

必须在 web.config 文件中启用 ASP.NET AJAX 身份验证服务:

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

身份验证服务要求启用 ASP.NET Forms 身份验证,并要求在客户端浏览器上启用 Cookie, (脚本无法启用无 Cookie 会话,因为无 cookie 会话需要 URL 参数) 。

启用并配置 AJAX 身份验证服务后,客户端脚本可以立即利用 Sys.Services.AuthenticationService 对象。 客户端脚本主要希望利用 login 方法和 isLoggedIn 属性。 存在几个属性来提供登录方法的默认值,该方法可以接受大量参数。

Sys.Services.AuthenticationService 成员

login 方法:

login () 方法开始请求对用户的凭据进行身份验证。 此方法是异步的,不会阻止执行。

参数:

参数名称 含义
userName 必需。 要进行身份验证的用户名。
password 可选 (默认为 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、set) :

此属性指定在与 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、set) :

此属性指定在注销 Web 服务调用完成时应调用的函数。 它应接收委托 (或函数引用) 。

此属性指定的函数引用应具有以下签名:

function AuthenticationLogoutCompletedCallback(result, userContext, methodName);

参数:

参数名称 含义
result 此参数将始终为 null;它保留供将来使用。
userContext 指定调用登录函数时提供的用户上下文信息。
methodName 调用方法的名称。

isLoggedIn 属性 (获取) :

此属性获取用户的当前身份验证状态;它由 ScriptManager 对象在页面请求期间设置。

如果用户当前登录,则此属性返回 true ;否则返回 false

path 属性 (get,设置) :

此属性以编程方式确定身份验证 Web 服务的位置。 它可用于替代默认的身份验证提供程序,以及在 ScriptManager 控件的 AuthenticationService 子节点 (的 Path 属性中以声明方式设置的一个集,有关详细信息,请参阅下面的使用自定义身份验证服务提供程序主题) 。

请注意,默认身份验证服务的位置不会更改。 但是,ASP.NET AJAX 允许指定提供与 ASP.NET AJAX 身份验证服务代理相同的类接口的 Web 服务的位置。

另请注意,不应将此属性设置为将脚本请求从当前站点定向到的值。 由于当前应用程序不会收到身份验证凭据,因此它将无用;此外,基础 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 分析服务也通过 ASP.NET AJAX 扩展公开。 由于 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、set) :

此属性指定在与 Web 服务通信失败时应调用的函数。 它应接收委托 (或函数引用) 。

此属性指定的函数引用应具有以下签名:

function AuthenticationFailureCallback(error, userContext, methodName);

参数:

参数名称 含义
错误 指定错误信息。
userContext 指定在调用 load 或 save 函数时提供的用户上下文信息。
methodName 调用方法的名称。

defaultSaveCompleted 属性 (get、set) :

此属性指定在保存用户配置文件数据完成后应调用的函数。 它应接收委托 (或函数引用) 。

此属性指定的函数引用应具有以下签名:

function ProfileSaveComplete(numPropsSaved, userContext, methodName);

参数:

参数名称 含义
numPropsSaved 指定已保存的属性数。
userContext 指定在调用 load 或 save 函数时提供的用户上下文信息。
methodName 调用方法的名称。

defaultLoadCompleted 属性 (get、set) :

此属性指定在完成加载用户配置文件数据后应调用的函数。 它应接收委托 (或函数引用) 。

此属性指定的函数引用应具有以下签名:

function ProfileLoadComplete(numPropsLoaded, userContext, methodName);

参数:

参数名称 含义
numPropsLoaded 指定加载的属性数。
userContext 指定在调用 load 或 save 函数时提供的用户上下文信息。
methodName 调用方法的名称。

path 属性 (get、set) :

此属性以编程方式确定配置文件 Web 服务的位置。 它可用于重写默认配置文件服务提供程序,以及在 ScriptManager 控件的 ProfileService 子节点的 Path 属性中以声明方式覆盖一个集。

请注意,默认配置文件服务的位置不会更改。 但是,ASP.NET AJAX 允许指定 Web 服务的位置,该服务提供与 ASP.NET AJAX 身份验证服务代理相同的类接口。

另请注意,此属性不应设置为将脚本请求从当前站点定向到的值。 基于 AJAX 的技术不应发布跨站点请求,并且可能会在客户端浏览器中生成安全异常。

此属性是一个 String 对象,表示配置文件 Web 服务的路径。

timeout 属性 (get、set) :

此属性确定在假设加载或保存请求失败之前等待配置文件服务的时间长度。 如果在等待调用完成时超时过期,将调用请求失败的回调,并且调用不会完成。

此属性是一个 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.cate@myKB.com 联系 Scott,也可以通过他的博客 在 ScottCate.com