Preemptive authorization problem when recording requests for Apache HTTP client

781 views
Skip to first unread message

Andrei Astrakharchik

unread,
Aug 2, 2017, 5:39:16 AM8/2/17
to wiremock-user
Hi Tom,

I'm starting a new thread for that. I discovered this issue as described in https://groups.google.com/forum/#!topic/wiremock-user/zO8Gm7nRdCM

Apache HTTP client does not send the credentials for Basic authentication unless it receives the 401 Authentication Failed response from the server, i.e. preemptive authentication is disabled. See discussion https://stackoverflow.com/questions/20914311/httpclientbuilder-basic-auth

It means that WireMock saves the 401 response at this point.

Now, the client re-sends the request with the credentials included and receives the 200 OK response. 

However, WireMock does not save it, because "Not recording mapping for /basic-auth/test_user/test_pass as this has already been received".

Is there a solution for this problem without enabling the preemptive authentication in Apache HTTP client?

Here is the scenario that I described:

31-07-2017_16:05:08 DEBUG [WireMock]: Proxying: GET http://httpbin.org/basic-auth/test_user/test_pass
31-07-2017_16:05:09 DEBUG [WireMock]: Request received:
127.0.0.1 - GET /basic-auth/test_user/test_pass

Connection: [keep-alive]
User-Agent: [Apache-HttpClient/4.5 (Java/1.8.0_91)]
Host: [localhost:59564]
Accept-Encoding: [gzip,deflate]



Matched response definition:
{
 
"status" : 200,
 
"proxyBaseUrl" : "http://httpbin.org"
}

Response:
HTTP
/1.1 401
Connection: [keep-alive]
Server: [meinheld/0.6.1]
Date: [Mon, 31 Jul 2017 13:05:06 GMT]
X
-Powered-By: [Flask]
X
-Processed-Time: [0.000400066375732]
Www-Authenticate: [Basic realm="Fake Realm"]
Access-Control-Allow-Origin: [*]
Access-Control-Allow-Credentials: [true]
Content-Length: [0]
Via: [1.1 vegur]



31-07-2017_16:05:09 DEBUG [WireMock]: Recording mappings for /basic-auth/test_user/test_pass
[Fatal Error] :1:1: Premature end of file.
31-07-2017_16:05:09 DEBUG [WireMock]: Proxying: GET http://httpbin.org/basic-auth/test_user/test_pass
31-07-2017_16:05:09 DEBUG [WireMock]: Request received:
127.0.0.1 - GET /basic-auth/test_user/test_pass

Connection: [keep-alive]
User-Agent: [Apache-HttpClient/4.5 (Java/1.8.0_91)]
Authorization: [Basic dGVzdF91c2VyOnRlc3RfcGFzcw==]
Host: [localhost:59564]
Accept-Encoding: [gzip,deflate]



Matched response definition:
{
 
"status" : 200,
 
"proxyBaseUrl" : "http://httpbin.org"
}

Response:
HTTP
/1.1 200
Connection: [keep-alive]
Server: [meinheld/0.6.1]
Date: [Mon, 31 Jul 2017 13:05:07 GMT]
Content-Type: [application/json]
Access-Control-Allow-Origin: [*]
Access-Control-Allow-Credentials: [true]
X
-Powered-By: [Flask]
X
-Processed-Time: [0.000518083572388]
Content-Length: [52]
Via: [1.1 vegur]

{
 
"authenticated": true,
 
"user": "test_user"
}

31-07-2017_16:05:09 DEBUG [WireMock]: Not recording mapping for /basic-auth/test_user/test_pass as this has already been received

Thank you,
Andrei Astra

Tom Akehurst

unread,
Aug 2, 2017, 5:59:48 AM8/2/17
to wiremock-user
Have you tried adding the Authorization header to the request you're making to WireMock?

Andrei Astrakharchik

unread,
Aug 2, 2017, 6:16:13 AM8/2/17
to wiremock-user
Yes, adding the Authorization header explicitly solves the problem. Also, caching the credentials does the trick. 

However, all the developers who use Apache HTTP client need to be aware of the issue. Is there any way to configure WireMock recording to handle non-preemptive authentication?

среда, 2 августа 2017 г., 12:59:48 UTC+3 пользователь Tom Akehurst написал:

Tom Akehurst

unread,
Aug 2, 2017, 6:20:25 AM8/2/17
to wiremock-user
If the client you're talking to WireMock with supports the the non-preemptive workflow, then I'd expect it to just work. You probably need to specify some headers to be captured when recording.

To me, putting it in the proxy is a hack - currently the proxy tries to be as transparent as possible, just passing single HTTP messages back and forth. Granted, there are exceptions e.g. gzip, but with something involving multiple steps like this I'd say it's the calling client's responsibility to manage the workflow.

Christian Schäfer

unread,
Nov 3, 2017, 8:11:56 AM11/3/17
to wiremock-user
Hello Tom,

we run into the same problem. The issue is that Wiremock only records the mapping of the 401 response, but not the 200 response. 

31-07-2017_16:05:09 DEBUG [WireMock]: Not recording mapping for /basic-auth/test_user/test_pass as this has already been received

The client is managing the workflow directly: It does the request again with authentication headers after receiving the 401 error. But in playback Wiremock doesn't replay the right responses since it only saves the first response with the 401 status but not the second response where the client sent the correct authentication.

As this is the standard basic authentication workflow I'd say Wiremock is currently unable to support it and requires clients to use preemptive authentication.

Best regards,
Christian.

Tom Akehurst

unread,
Nov 10, 2017, 4:56:47 AM11/10/17
to wiremock-user
1) Have you tried using the new (rather than legacy) record feature?
2) When you started recording, did you tell WireMock to consider the Authorization header a request parameter?

Andrei Astrakharchik

unread,
Nov 10, 2017, 5:47:36 AM11/10/17
to wiremock-user
(1) Worked for me. I think I've mentioned that in a different thread.

пятница, 10 ноября 2017 г., 12:56:47 UTC+3 пользователь Tom Akehurst написал:
Reply all
Reply to author
Forward
0 new messages