使用脚本进行身份验证
本部分演示如何编写使用 WinHttpRequest 对象从需要 HTTP 身份验证的服务器访问数据的脚本。
先决条件和要求
除了 Microsoft JScript 的实践知识外,此示例还要求满足以下条件:
- Microsoft Windows 软件开发工具包的当前版本 (SDK) 。
- 如果通过代理服务器连接到 Internet,则为 Microsoft Windows HTTP Services (WinHTTP) 建立代理设置的代理配置工具。 有关详细信息 ,请参阅Proxycfg.exe代理配置工具 。
- 熟悉 网络术语 和概念。
使用身份验证访问网站
若要创建演示身份验证的脚本,请执行以下操作:
打开文本编辑器,例如 Microsoft 记事本。
将“[authenticationSite]”替换为相应的文本后,将以下代码复制到文本编辑器中,以指定需要 HTTP 身份验证的站点的 URL。
// Load the WinHttpRequest object. var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); function getText1( ) { // Specify the target resource. WinHttpReq.open( "GET", "https://[authenticationSite]", false; // Send a request to the server and wait for a response. WinHttpReq.send( ); // Display the results of the request. WScript.Echo( "No Credentials: " ); WScript.Echo( WinHttpReq.Status + " " + WinHttpReq.StatusText); WScript.Echo( WinHttpReq.GetAllResponseHeaders); WScript.Echo( ); }; function getText2( ) { // HttpRequest SetCredentials flags HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0; // Specify the target resource. WinHttpReq.open( "GET", "https://[authenticationSite]", false ); // Set credentials for server. WinHttpReq.SetCredentials( "User Name", "Password", HTTPREQUEST_SETCREDENTIALS_FOR_SERVER); // It might also be necessary to supply credentials // to the proxy if you connect to the Internet // through a proxy that requires authentication. // Send a request to the server and wait for // a response. WinHttpReq.send( ); // Display the results of the request. WScript.Echo( "Credentials: " ); WScript.Echo( WinHttpReq.Status + " " + WinHttpReq.StatusText ); WScript.Echo( WinHttpReq.GetAllResponseHeaders( ) ); WScript.Echo( ); }; getText1( ); getText2( );
将文件另存为“Auth.js”。
在命令提示符下,键入“cscript Auth.js”,然后按 Enter。
现在,你有一个以两种不同的方式请求资源的程序。 第一种方法在不提供凭据的情况下请求资源。 返回 401 状态代码以指示服务器需要身份验证。 响应标头也会显示,应如下所示:
Connection: Keep-Alive
Content-Length: 0
Date: Fri, 27 Apr 2001 01:47:18 GMT
Content-Type: text/html
Server: Microsoft-IIS/5.0
WWW-Authenticate: NTLM
WWW-Authenticate: Negotiate
Cache-control: private
尽管响应指示对资源的访问被拒绝,但它仍然返回几个标头,这些标头提供有关资源的一些信息。 名为“WWW-Authenticate”的标头指示服务器需要对此资源进行身份验证。 如果存在名为“Proxy-Authenticate”的标头,则表示代理服务器需要身份验证。 每个身份验证标头都包含可用的身份验证方案,有时还包含一个领域。 领域值区分大小写,并定义一组应接受相同凭据的服务器或代理。
有两个名为“WWW-Authenticate”的标头,指示支持多个身份验证方案。 如果调用 GetResponseHeader 方法来查找“WWW-Authenticate”标头,该方法仅返回该名称的第一个标头的内容。 在这种情况下,它将返回值“NTLM”。 若要确保处理标头的所有匹配项,请改用 GetAllResponseHeaders 方法。
第二个方法调用请求相同的资源,但首先通过调用 SetCredentials 方法提供身份验证凭据。 以下代码部分演示如何使用此方法。
WinHttpReq.SetCredentials( "User Name", "Password",
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER);
此方法将用户名设置为“UserName”,将密码设置为“Password”,并指示授权凭据应用于资源服务器。 身份验证凭据也可以发送到代理。
提供凭据后,服务器将返回 200 状态代码,指示可以检索文档。
检查状态代码
前面的示例是说明性的,但它要求用户显式提供凭据。 在必要时提供凭据,在不需要时不提供凭据的应用程序更有用。 若要实现执行此操作的功能,必须修改示例,以检查随响应一起返回的状态代码。
有关可能的状态代码的完整列表以及说明,请参阅 HTTP 状态代码。 但是,对于此示例,应只遇到三个代码中的一个。 状态代码为 200 表示资源可用且正在随响应一起发送。 状态代码 401 指示服务器需要身份验证。 状态代码 407 指示代理需要身份验证。
通过将“getText2”函数替换为以下代码来修改在上一部分中创建的示例, (将“[authenticationSite]”替换为你自己的文本,以指定需要 HTTP 身份验证) 站点的 URL:
function getText2() {
WScript.Echo( "Credentials: " );
// HttpRequest SetCredentials flags.
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0;
HTTPREQUEST_SETCREDENTIALS_FOR_PROXY = 1;
// Specify the target resource.
var targURL = "https://[authenticationSite]";
WinHttpReq.open( "GET", targURL, false );
var Done = false;
var Attempts = 0;
do
{
// Keep track of the number of request attempts.
Attempts++;
// Send a request to the server and wait for a response.
WinHttpReq.send( );
// Obtain the status code from the response.
var Status = WinHttpReq.Status;
switch (Status)
{
// A 200 status indicates that the resource was retrieved.
case 200:
Done = true;
break;
// A 401 status indicates that the server
// requires authentication.
case 401:
WScript.Echo( "Requires Server UserName and Password." );
// Specify the target resource.
WinHttpReq.open( "GET", targURL, false );
// Set credentials for the server.
WinHttpReq.SetCredentials( "User Name",
"Password",
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER);
break;
// A 407 status indicates that the proxy
// requires authentication.
case 407:
WScript.Echo( "Requires Proxy UserName and Password." );
// Specify the target resource.
WinHttpReq.open( "GET", targURL, false );
// Set credentials for the proxy.
WinHttpReq.SetCredentials( "User Name",
"Password",
HTTPREQUEST_SETCREDENTIALS_FOR_PROXY );
break;
}
} while( ( !Done ) && ( Attempts < 3 ) );
// Display the results of the request.
WScript.Echo( WinHttpReq.Status + " " + WinHttpReq.StatusText );
WScript.Echo( WinHttpReq.GetAllResponseHeaders( ) );
WScript.Echo( );
};
同样,保存并运行文件。 第二种方法仍检索文档,但它仅在需要时提供凭据。 “getText2”函数执行 Open 和 Send 方法,就像不需要身份验证一样。 使用 Status 属性检索状态,switch 语句响应生成的状态代码。 如果状态为 401 (服务器需要身份验证) 或 407 (代理要求身份验证) ,则再次执行 Open 方法。 然后是 SetCredentials 方法,该方法设置用户名和密码。 然后,代码循环回到 Send 方法。 如果在三次尝试后无法成功检索资源,则该函数将停止执行。
相关主题