I finally got things working but it wasn't without some extra investigative effort ...
For the benefit of others I'll go over the details :
My requirements were similar to those mentioned in another thread http://forum.springframework.org/viewtopic.php?t=2321
so I knew that one could configure Acegi to work with FORM and BASIC authentication by providing the following filter chain
Code:
httpSessionContextIntegrationFilter,authenticationProcessingFilter,basicProcessingFilter,securityEnforcementFilter
I configured my server with both FORM and BASIC authentication however despite my setting the credentials for BASIC authentication in the client VBA code, the response I'd get was still the contents of my login page.
After reading "Basic Authentication Scheme" in RFC 1945 #11.1, I learnt how BASIC authentication is supposed to work.
The client issues a request for a URL and the server denies access with a 401 status code AND a response header WWW-Authenticate that looks like the following
Code:
WWW-Authenticate: Basic realm="MyRealm"
When the browser receives a 401 status response it looks for the authentication scheme in the "WWW-Authenticate" header. When it finds an authentication scheme of 'Basic' it pops up a dialog box prompting the user login and when the user clicks 'Ok' it resubmits the request but this time encodes the user name and password in the header.
Here is an example of the wire contents in a BASIC authentication based login.
Code:
REQUEST
GET /test.html HTTP/1.1
Accept: */*
User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
Host: localhost
Connection: Keep-Alive
GET /test.html HTTP/1.1
Accept: */*
User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
Host: localhost:9000
Connection: Keep-Alive
Authorization: Basic VVNFUk5BTUU6UEFTU1dPUkQ=
RESPONSE
HTTP/1.1 401 Authorization Required
Date: Tue, 29 Mar 2005 16:28:08 GMT
Server: Apache/1.3.31 (Unix)
WWW-Authenticate: Basic realm="MyRealm"
Set-Cookie: path=/; expires=Wednesday, 29-Mar-2006 23:59:59 GMT
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/xml; charset=utf-8
HTTP/1.1 401 Authorization Required
Date: Tue, 29 Mar 2005 16:28:08 GMT
Server: Apache/1.3.31 (Unix)
WWW-Authenticate: Basic realm="MyRealm"
Set-Cookie: path=/; expires=Wednesday, 29-Mar-2006 23:59:59 GMT
Vary: Authorization
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/xml; charset=utf-8
121
<html>
<head>
</head>
<body>
Hello World!
</body>
</html>
When running with both FORM and BASIC authentication where the authentication entry point is AuthenticationProcessingFilterEntryPoint,
Acegi does not add the "WWW-Authenticate" header in the response because it needs to redirect to the login form url of the configured AuthenticationProcessingFilterEntryPoint.
Now back to my VBA code
Code:
Dim myReq As WinHttpRequest
Set myReq = New WinHttpRequest
myReq.Open "GET", "http://mywebapp:8080/orders/data.do", False
'Set credentials
myReq.SetCredentials "myUserName", "myPassword", HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
The SetCredentials method on the WinHttpRequest object wasn't working because it expects the same (2 phase) exchange protocol as a browser when running with BASIC auth alone. On a denied request, the WinHttpRequest object would examine the "WWW-Authenticate" header to figure out the authentication scheme and accordingly apply the provided user name password. However since Acegi does not set on the response when running with FORM + BASIC auth, the credentials were not being applied to by the WinHttpRequest object. (Besides the 'Basic' auth scheme, WinHttpRequest supports Digest, NTLM, Passport and Negotiate)
So to get this working, I read the format of the user name/passoword that is required in the request header for Basic authentication and I'm setting it manually in the VBA code.
Code:
Authorization: Basic Base64(<username>:<password>)
Now everything works perfectly.
Acegi Rocks!! and being opensource definitely helps.
Thanks,
Sanjiv