How can I prevent GWT from trying to append an Authorization header to an RPC POST? (bug?)

232 views
Skip to first unread message

dblock

unread,
May 15, 2010, 11:33:15 AM5/15/10
to Google Web Toolkit
There's something strange going on with RPC POSTs when we do Negotiate/
NTLM/Kerberos auth. I have a server that responds with a 401 on a GET,
we negotiate windows authentication properly, the GWT tries to make an
RPC call and somehow carries an Authorization: header in the request.
This breaks everything because that ticket is no longer valid.

Let me illustrate this in detail.


GET /dbprotect/com.appsec.console.gwt.main/DbProtect.html HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/
xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap,
application/x-ms-application, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/
4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR
3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Accept-Encoding: gzip, deflate
Host: localhost:20080
Connection: Keep-Alive

The response is correct, we're going to do NTLM.

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Wed, 31 Dec 1969 19:00:00 EST
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
Connection: close
Transfer-Encoding: chunked
Date: Sat, 15 May 2010 15:21:20 GMT

GET /dbprotect/com.appsec.console.gwt.main/DbProtect.html HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/
xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap,
application/x-ms-application, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/
4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR
3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Accept-Encoding: gzip, deflate
Host: localhost:20080
Connection: Keep-Alive
Authorization: Negotiate
TlRMTVNTUAABAAAAB7IIogkACQAxAAAACQAJACgAAAAFAs4OAAAAD0RET1VCLVJFRFdPUktHUk9VUA==

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Wed, 31 Dec 1969 19:00:00 EST
Connection: keep-alive
WWW-Authenticate: Negotiate TlRMTVNTUAACAAAEgASADgAAAAFwoqi
+etpKdZFlmSIswIBAAAAAFwAXABKAAAABQLODgAAAA9EAEQATwBVAEIALQBSAEUARAACABIARABEAE8AVQBCAC0AUgBFAEQAAQASAEQARABPAFUAQgAtAFIARQBEAAQAEgBkAGQAbwB1AGIALQByAGUAZAADABIAZABkAG8AdQBiAC0AcgBlAGQAAAAAAA==
Transfer-Encoding: chunked
Date: Sat, 15 May 2010 15:21:20 GMT

GET /dbprotect/com.appsec.console.gwt.main/DbProtect.html HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/
xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap,
application/x-ms-application, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/
4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR
3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Accept-Encoding: gzip, deflate
Host: localhost:20080
Connection: Keep-Alive
Authorization: Negotiate
TlRMTVNTUAADAAAAAAAAAEgAAAAAAAAASAAAAAAAAABIAAAAAAAAAEgAAAAAAAAASAAAAAAAAABIAAAABcKIogUCzg4AAAAP

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Wed, 31 Dec 1969 19:00:00 EST
Set-Cookie: JSESSIONIDSSO=EF1833CB2F53FBAFF6CFA6E00468DCC2; Path=/
Set-Cookie: JSESSIONID=7807DF94DAAE28A526809C1DE106296D; Path=/
dbprotect
Set-Cookie:
dbprotect_cred=v1794E77624855386B357338612F6F70307046334D6E6769524A52664852756F476375543464344A774356343D;
Path=/
ETag: W/"1783-1273936107708"
Last-Modified: Sat, 15 May 2010 15:08:27 GMT
Content-Type: text/html
Content-Length: 1783
Date: Sat, 15 May 2010 15:21:20 GMT

We're now authenticated, all good and ready to party.

GET /dbprotect/com.appsec.console.gwt.main/
com.appsec.console.gwt.main.nocache.js HTTP/1.1
HTTP/1.1 200 OK
GET /dbprotect/com.appsec.console.gwt.main/css/ext-all.css HTTP/1.1
HTTP/1.1 200 OK
GET /dbprotect/com.appsec.console.gwt.main/images/icons/favicon.ico
HTTP/1.1
HTTP/1.1 200 OK
GET /dbprotect/com.appsec.console.gwt.main/gwt/standard/standard.css
HTTP/1.1
HTTP/1.1 200 OK
GET /dbprotect/com.appsec.console.gwt.main/AssetManagementUI.css HTTP/
1.1
HTTP/1.1 200 OK
GET /dbprotect/com.appsec.console.gwt.main/AdministrationUI.css HTTP/
1.1
HTTP/1.1 200 OK
GET /dbprotect/com.appsec.console.gwt.main/
99FEA2E9AD798EF33761EA2CF35159FF.cache.html HTTP/1.1
HTTP/1.1 200 OK
GET /dbprotect/com.appsec.console.gwt.main/DbProtect.css HTTP/1.1
HTTP/1.1 200 OK

The next request was inserted for testing via HttpRequest.asyncPost,
it's succeeding.

POST /dbprotect/com.appsec.console.gwt.main/DbProtect.html?async HTTP/
1.1
Accept: */*
Accept-Language: en-us
Referer: http://localhost:20080/dbprotect/com.appsec.console.gwt.main/99FEA2E9AD798EF33761EA2CF35159FF.cache.html
Content-Type: text/plain; charset=utf-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/
4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR
3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Host: localhost:20080
Content-Length: 0
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=7807DF94DAAE28A526809C1DE106296D;
JSESSIONIDSSO=EF1833CB2F53FBAFF6CFA6E00468DCC2;
dbprotect_cred=v1794E77624855386B357338612F6F70307046334D6E6769524A52664852756F476375543464344A774356343D

HTTP/1.1 200 OK
...

The next request is wrong. It should not have an Authorization header!
We're already finished with that. Where is this coming from? (RPC
call)

POST /dbprotect/com.appsec.console.gwt.main/service/DbProtectRPC HTTP/
1.1
Accept: */*
Accept-Language: en-us
Referer: http://localhost:20080/dbprotect/com.appsec.console.gwt.main/99FEA2E9AD798EF33761EA2CF35159FF.cache.html
Content-Type: text/x-gwt-rpc; charset=utf-8
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/
4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR
3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Host: localhost:20080
Content-Length: 0
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=7807DF94DAAE28A526809C1DE106296D;
JSESSIONIDSSO=EF1833CB2F53FBAFF6CFA6E00468DCC2;
dbprotect_cred=v1794E77624855386B357338612F6F70307046334D6E6769524A52664852756F476375543464344A774356343D
Authorization: Negotiate
TlRMTVNTUAABAAAAB7IIogkACQAxAAAACQAJACgAAAAFAs4OAAAAD0RET1VCLVJFRFdPUktHUk9VUA==

This negotiate token is invalid, it has been used, so we can't auth
any more. Even if we could, this POST is missing a body and will fail.

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Connection: keep-alive
WWW-Authenticate: Negotiate TlRMTVNTUAACAAAAEgASADgAAAAFwoqiDf/
vgfYXpoEgtwIBAAAAAFwAXABKAAAABQLODgAAAA9EAEQATwBVAEIALQBSAEUARAACABIARABEAE8AVQBCAC0AUgBFAEQAAQASAEQARABPAFUAQgAtAFIARQBEAAQAEgBkAGQAbwB1AGIALQByAGUAZAADABIAZABkAG8AdQBiAC0AcgBlAGQAAAAAAA==
Transfer-Encoding: chunked
Date: Sat, 15 May 2010 15:21:22 GMT


What's going on here? Any help appreciated.
GXT 1.2.4 and GWT 1.5.3

-dB.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

dblock

unread,
May 19, 2010, 7:40:50 AM5/19/10
to Google Web Toolkit
This issue is resolved.

The problem was in our NTLM implementation. NTLM, unlike other
protocols, does a POST without a body first, receives a 401, then does
a POST with a body. It took some careful reading of the RFC to figure
that out. So it's all by design. Note that NTLM is also chatty, it
will do auth every POST.

Fyi: we'll be contributing a SPNEGO filter for Tomcat that supports
Kerberos, Negotiate and NTLM to Waffle (http://waffle.codeplex.com)
shortly.
Reply all
Reply to author
Forward
0 new messages