This topic descrbes how to write a Microsoft Visual Basic application that uses the
WinHttpRequest object to access data from a server that requires HTTP authentication.
Prerequisites and Requirements
In addition to a working knowledge of Visual Basic, this example requires:
- The
current version of the Platform Software Development Kit (SDK).
- Microsoft Internet Explorer 5.01 or later.
- The proxy configuration tool to establish the proxy settings for Microsoft Windows HTTP Services (WinHTTP), if your connection to the Internet is through a proxy server. For more information, see
ProxyCfg.exe, a Proxy Configuration Tool.
- A familiarity with
network terminology and concepts.
The example also assumes familiarity with requesting a network resource using the
WinHttpRequest object. For more information, see
Retrieving Data Using Visual Basic.
Accessing a Web Site With Authentication
To create a Visual Basic application that demonstrates authentication, begin by opening Visual Basic and creating a new Standard EXE project. The new project contains a form named Form1.
The application uses some of the methods and properties of the
WinHttpRequest object. Use the following procedure to use early binding to access this object.
To access a Web site with authentication
- Choose References from the Project.
- Select Microsoft WinHttpRequest Component, version 5.0 from the list of Available References and click OK.
If the
WinHttpRequest object is not available on the
Available References list, WinHttp.dll has not
been
properly installed or is not registered. When you use early binding with a
Component Object Model (COM) object, Visual Basic is aware of the methods and
properties for that object and can provide assistance with syntax checking.
It
is also able to call the methods and properties faster.
Create a user interface for the application by using the tools provided in Visual Basic. The form should include two
CommandButton controls named Command1 and Command2, and two
TextBox controls named Text1 and Text2. Arrange the controls so that the form looks similar to the following image.
.png)
Copy the following code example in the code area of the project:
Dim WinHttpReq As WinHttp.WinHttpRequest
Const HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0
Const HTTPREQUEST_SETCREDENTIALS_FOR_PROXY = 1
Private Sub Form_Load()
' Create an instance of the WinHttpRequest object.
Set WinHttpReq = New WinHttpRequest
End Sub
' This subroutine requests a resource without supplying
' authentication credentials.
Private Sub Command1_Click()
' Assemble an HTTP request.
WinHttpReq.Open "GET", _
"http://msdn.microsoft.com/downloads/samples/internet" & _
"/winhttp/auth/authenticate.asp", False
' Send the HTTP Request.
WinHttpReq.Send
' Display the status code and response headers.
Text2.Text = WinHttpReq.Status & " " & WinHttpReq.StatusText
Text1.Text = WinHttpReq.GetAllResponseHeaders_
& " " & WinHttpReq.ResponseText
End Sub
' This subroutine requests a resource and supplies
' authentication credentials.
Private Sub Command2_Click()
' Assemble an HTTP request.
WinHttpReq.Open "GET", _
"http://msdn.microsoft.com/downloads/samples/internet" & _
"/winhttp/auth/authenticate.asp", False
' Set the user name and password.
WinHttpReq.SetCredentials "UserName", "Password", _
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
' Send the HTTP Request.
WinHttpReq.Send
' Display the status code and response headers.
Text2.Text = WinHttpReq.Status & " " & WinHttpReq.StatusText
Text1.Text = WinHttpReq.GetAllResponseHeaders &_
" " & WinHttpReq.ResponseText
End Sub
This application attempts to access a resource in two different ways. If you click the
CommandButton on the left, the application requests a resource without sending authentication credentials. This technique is described in detail in
Retrieving Data Using Visual Basic so the source code is not analyzed here in detail. Because the server requires authentication for this resource, you receive a 401 status code, which is displayed in the lower
TextBox. The response headers are displayed in the upper
TextBox and should be similar to the following headers:
Connection: Keep-Alive
Content-Length: 0
Date: Fri, 27 Apr 2001 01:47:18 GMT
Content-Type: text/html
Proxy-Support: Session-Based-Authentication
Server: TEST-IIS/5.0
WWW-Authenticate: NTLM
WWW-Authenticate: Negotiate
Cache-control: private
Although the response indicates that access to the resource was denied, it still returns several headers that provide some information about the resource. The header named "WWW-Authenticate" indicates that the server requires authentication for this resource. If there was a header named "Proxy-Authenticate", it would indicate that the proxy server requires authentication. Each authenticate header contains an available authentication scheme and sometimes a realm. The realm value is case-sensitive and defines a protection space on the proxy or server. For example, the following header entry indicates that a Basic authentication is required and the realm is "example".
WWW-Authenticate: Basic Realm="example"
For the resource requested by this application, there are two headers named "WWW-Authenticate", which indicate that multiple authentication schemes are supported. When you click the
CommandButton on the right, credentials are sent along with the request for the resource by using the following code:
WinHttpReq.SetCredentials "UserName", "Password", _
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
This sets the user name to "UserName", the password to "Password", and indicates that the authorization credentials apply to the resource server. To apply the authorization credentials to the proxy server, set the last parameter to HTTPREQUEST_SETCREDENTIALS_FOR_PROXY. WinHTTP uses the preferred authentication scheme based on the security of available schemes. Ideally, when credentials are sent with the request, the document is successfully retrieved with a 200 status code. The document contents and headers are displayed in the upper
TextBox. For more information and a list of other possible status codes, see
HTTP Status Codes.
Checking the Status Codes
The previous example is instructional, but requires that the application user explicitly choose to supply credentials. An application that supplied credentials when it was necessary and did not supply credentials when it was not necessary would be more useful. To implement this feature, you must modify your example to examine the status code returned with the response.
For more information and a complete list of possible status codes, along with descriptions, see
HTTP Status Codes. For this example, however, you should encounter only one of three codes. A status code of 200 indicates that a resource is available and is being sent with the response. A status code of 401 indicates that the server requires authentication. A status code of 407 indicates that the proxy requires authentication.
Make the following modifications to the "Command2_Click" subroutine to implement this change.
- Create local variables to store the URL of the resource and to keep track of when a request should be repeated. Copy and paste the relevant lines below directly into your Visual Basic application.
' This subroutine requests a resource and supplies
' authentication credentials.
Private Sub Command2_Click()
Dim bDone As Boolean ' True when resource is retrieved
Dim iAttempts As Long ' Number of request attempts
Dim sURL As String ' URL of the resource
' Initialize local variables.
bDone = False
iAttempts = 0
sURL = "http://msdn.microsoft.com/downloads/samples/internet" & _
"/winhttp/auth/authenticate.asp"
' Assemble an HTTP request.
WinHttpReq.Open "GET", sURL, False
- Remove the code that calls the
SetCredentials method. It is added again in a later step, but it should not execute before the initial request is sent.
- Place the
Send method inside a loop that occurs no more that three times. If the requested document cannot be retrieved after three attempts, break out of the loop.
' Assemble an HTTP request.
WinHttpReq.Open "GET", sURL, False
Do
iAttempts = iAttempts + 1
' Send the HTTP Request.
WinHttpReq.Send
Loop Until bDone Or (iAttempts > 3)
- Finally, check the status code returned by the server. If the status code is 200, the document was retrieved and the application is done. If a 401 or 407 status is received, authentication is required. In these cases,
SetCredentials is called to provide a user name and password and a new request is opened.
Do
iAttempts = iAttempts + 1
' Send the HTTP Request.
WinHttpReq.Send
' Check the status code returned from the server.
Select Case WinHttpReq.Status
Case 200 ' Document retrieved
bDone = True
Case 401 ' Server requires authentication
' Alert user that authentication is required.
MsgBox "Server requires authentication."
' Assemble a new HTTP request.
WinHttpReq.Open "GET", sURL, False
' Set the user name and password.
WinHttpReq.SetCredentials _
"UserName", _
"Password", _
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
Case 407 ' Proxy requires authentication
' Alert user that authentication is required.
MsgBox "Proxy requires authentication."
' Assemble a new HTTP request.
WinHttpReq.Open "GET", sURL, False
' Set the user name and password.
WinHttpReq.SetCredentials _
"UserName", _
"Password", _
HTTPREQUEST_SETCREDENTIALS_FOR_PROXY
End Select
Loop Until bDone Or (iAttempts > 3)
Now when you run the application and click the button on the right, the upper
TextBox fills with headers and content as in the first example. You are alerted with a message box if authentication is required.
See Also
- Authentication in
WinHTTP
- SetCredentials
- HTTP/1.1
Request for Comments
(RFC)
Send comments about this topic to Microsoft
Build date: 3/12/2009