Elad Tabak
Elad Tabak

Reputation: 2417

Curl authorization

I have spring security with https settings.

I'm seeing an unexpected behavior when trying to run curl GET on a URL in a secure way.

When curl first sends a request to the server, it does it with no authorization data (why? I specifically added it). Then, the server reply with Authentication Error (401). The client then re-transmits the request, this time with authorization data, and the server replies properly with the required data.

Any idea why this happens?

Curl command:

curl -v --insecure --anyauth --user username:password -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:8443/myresource

Request 1:

> GET /myresource HTTP/1.1
> User-Agent: curl/7.21.3 (x86_64-redhat-linux-gnu) libcurl/7.21.3 NSS/3.13.1.0 zlib/1.2.5 libidn/1.19 libssh2/1.2.7
> Host: localhost:8443
> Accept: application/json
> Content-Type: application/json

Response 1:

< HTTP/1.1 401 Unauthorized
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=B56A7F49E715795B5D1158DB192710AA; Path=/myresource ; Secure; HttpOnly
< WWW-Authenticate: Digest realm="Protected", qop="auth", nonce="MTM0Njg2MjYwMjY0ODozNDk5ZDkxNTYxNjMxMDJmNDA4MWQ1NTBmZjk5OGQ5Nw=="
< Content-Type: text/html;charset=utf-8
< Content-Length: 1119
< Date: Wed, 05 Sep 2012 16:29:52 GMT

Request 2:

> GET /myresource HTTP/1.1
> Authorization: Digest username="username", realm="Protected", nonce="MTM0Njg2MjYwMjY0ODozNDk5ZDkxNTYxNjMxMDJmNDA4MWQ1NTBmZjk5OGQ5Nw==", uri="/myresource", cnonce="ODczNjg0", nc=00000001, qop="auth", response="58faded9ae5f639ba0056fb86edca71f"
> User-Agent: curl/7.21.3 (x86_64-redhat-linux-gnu) libcurl/7.21.3 NSS/3.13.1.0 zlib/1.2.5 libidn/1.19 libssh2/1.2.7
> Host: localhost:8443
> Accept: application/json
> Content-Type: application/json

Response 2:

< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=37F375C5663C4A049D95D49C7C1CF0FD; Path=/myresource ; Secure; HttpOnly
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Wed, 05 Sep 2012 16:29:52 GMT

Upvotes: 5

Views: 34214

Answers (2)

Benjamin Close
Benjamin Close

Reputation: 341

Digest authentication cannot take place without the first 401 response from the server.

Ie: The server replies to the first request with:

WWW-Authenticate: Digest realm="Protected", qop="auth", nonce="MTM0Njg2MjYwMjY0ODozNDk5ZDkxNTYxNjMxMDJmNDA4MWQ1NTBmZjk5OGQ5Nw=="

The client needs this information before it can assemble a valid digest authentication request. Digest requires the nonce and the op method to use in order to provide a valid

response="58faded9ae5f639ba0056fb86edca71f"

as shown in the second request.

So in short you can't do a digest request without without first getting the 401 as you don't have enough information to assemble the response without it.

Upvotes: 4

Kylos
Kylos

Reputation: 1938

From man curl:

--anyauth

(HTTP) Tells curl to figure out authentication method by itself, and use the most secure one the remote site claims to support. This is done by first doing a request and checking the response-headers, thus possibly inducing an extra network round-trip. This is used instead of setting a specific authentication method, which you can do with --basic, --digest, --ntlm, and --negotiate.

Note that using --anyauth is not recommended if you do uploads from stdin, since it may require data to be sent twice and then the client must be able to rewind. If the need should arise when uploading from stdin, the upload operation will fail.

You should use --digest instead of --anyauth.

Upvotes: 9

Related Questions