Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuget not sending basic auth header. #599

Closed
patrickjamesbarry opened this issue May 15, 2015 · 10 comments
Closed

Nuget not sending basic auth header. #599

patrickjamesbarry opened this issue May 15, 2015 · 10 comments
Assignees
Labels
Priority:2 Issues for the current backlog. Type:Bug
Milestone

Comments

@patrickjamesbarry
Copy link

I am in VS 2015, Version 14.0.22823.1 D14REL, using nuget package manager 3.0. During a nuget restore, it is not sending the basic auth header on all requrests. What is weird is that it DOES on some requests. Here is fiddler capture of just headers...

This nuget restore occurs when I try to add Nunit to my project.

GET http://company.artifactoryonline.com/company/api/nuget/my-nuget-virtual/FindPackagesById()?Id='NUnit' HTTP/1.1
Authorization: Basic xxxxxxxxx
Host: company.artifactoryonline.com
Connection: Keep-Alive

HTTP/1.1 200 OK
Content-Type: application/atom+xml;charset=utf-8
DataServiceVersion: 2.0
Date: Fri, 15 May 2015 13:18:58 GMT
Server: nginx
X-Node: nginx1-use-1d
Connection: keep-alive
Content-Length: 582

GET http://company.artifactoryonline.com/company/api/nuget/my-nuget-local/FindPackagesById()?Id='NUnit' HTTP/1.1
Authorization: Basic xxxxxxxxx
Host: company.artifactoryonline.com
Connection: Keep-Alive

HTTP/1.1 200 OK
Content-Type: application/atom+xml;charset=utf-8
DataServiceVersion: 2.0
Date: Fri, 15 May 2015 13:18:58 GMT
Server: nginx
X-Node: nginx2-use-1d
Connection: keep-alive
Content-Length: 578

GET http://company.artifactoryonline.com/company/api/nuget/my-nuget-local/my/Alliances/FindPackagesById()?Id='NUnit' HTTP/1.1
Authorization: Basic xxxxxxxxx
Host: company.artifactoryonline.com
Connection: Keep-Alive

HTTP/1.1 200 OK
Content-Type: application/xml;charset=utf-8
DataServiceVersion: 1.0
Date: Fri, 15 May 2015 13:18:58 GMT
Server: nginx
X-Node: nginx1-use-1c
Connection: keep-alive
Content-Length: 407

GET http://company.artifactoryonline.com/company/api/nuget/my-nuget-local/my/Alliances/FindPackagesById()?Id='NUnit' HTTP/1.1
Host: company.artifactoryonline.com
Connection: Keep-Alive

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=ISO-8859-1
Date: Fri, 15 May 2015 13:18:58 GMT
Server: nginx
WWW-Authenticate: Basic realm="Artifactory Realm"
Content-Length: 92
Connection: keep-alive

@patrickjamesbarry
Copy link
Author

I am using Artifactory in the cloud, and none of my local repositories I have registered with nuget (sources Add xxx with credentials are working. I captured web traffic, and once again the Auth header is missing. The interesting thing is that a 2nd attempt is sent WITH the header, and then that request fails with 406. I am going to ask Artifactory support about this, however, why is basic auth not getting sent on first request to begin with?

GET http://company.artifactoryonline.com/company/api/nuget/thirdparty-nuget-local/my/Packages()?$filter=((((Id%20ne%20null)%20and%20substringof('nunit',tolower(Id)))%20or%20((Description%20ne%20null)%20and%20substringof('nunit',tolower(Description))))%20or%20((Tags%20ne%20null)%20and%20substringof('%20nunit%20',tolower(Tags))))%20and%20IsAbsoluteLatestVersion&$orderby=DownloadCount%20desc,Id HTTP/1.1
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 2.0;NetFx
User-Agent: NuGet/3.0.0 (NuGet.Client.Interop, CORE, host)
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
Host: company.artifactoryonline.com
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=ISO-8859-1
Date: Fri, 15 May 2015 14:12:42 GMT
Server: nginx
WWW-Authenticate: Basic realm="Artifactory Realm"
Content-Length: 92
Connection: keep-alive

{
"errors" : [ {
"status" : 401,
"message" : "Authentication is required."
} ]
}

@feiling
Copy link

feiling commented May 20, 2015

@patrickjamesbarry I checked our code and didn't find anything wrong. I set up a server with basic authentication and verified (with fiddler of course) that NuGet does send out basic authentication headers (on the 2nd request).

Note that every request will be sent twice. The response of the first request will be 401, and it contains the challenge, e.g.

HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/8.5
WWW-Authenticate: Basic realm="xxx"
X-Powered-By: ASP.NET
Date: Wed, 20 May 2015 20:04:10 GMT
Connection: close
Content-Length: 0

The line WWW-Authenticate: Basic realm="xxx" tells NuGet that the server needs basic authentication. So NuGet will send the same request again, this time with the header

Authorization: Basic xxxx

Could you check that

@patrickjamesbarry
Copy link
Author

I'll have to check that, but if you register credentials with a nuget source, why would you wait for a failure before you send the credentials? Even if some nuget providers do not use basic auth (which I am not familiar with any), wouldn't it make sense to at least try basic auth on the first request, since it is by far, the most popular authentication protocol? Seems like a waste to always fail on the first request, when we have access to the credentials.

@xavierdecoster
Copy link
Member

Note that every request will be sent twice.

@feiling what do you mean with "every request"?

Having client latency and server load in mind, we should only do the auth handshake on the initial request and reuse it for subsequent requests to the same package source. Is this what we currently do?

@patrickjamesbarry
Copy link
Author

@feiling
If I add a new Source...
nuget sources Add -Name Artifactory -Source http://company.artifactoryonline.com/company./api/nuget/inin-nuget-local -UserName patric
k.barry -Password xxxx

Then setup the apikey
nuget setapikey patrick.barry:xxxx -Source Artifactory

and then push a package...
push mypackage.1.0.0.nupkg Artifactory

I think what I am hearing, is that even though I have specified credentials, we still need the first request to fail, before we actually send the auth header set? Am I understanding this correctly?

@feiling
Copy link

feiling commented May 21, 2015

@xavierdecoster, @patrickjamesbarry , we didn't set PreAuthenticate (https://msdn.microsoft.com/en-us/library/system.net.webrequest.preauthenticate(v=vs.110).aspx) to true, so no authentication in subsequent requests. Probably this is something we should consider to do. However, this code has been there for a LONG time, and I fear that there was a good reason that PreAuthenticate was not set to true in the first place.

Note that no matter what you do, no authentication header is sent in the very first request.

@patrickjamesbarry
Copy link
Author

That sounds like a low hanging fruit of something to fix.

@feiling
Copy link

feiling commented Jun 4, 2015

@patrickjamesbarry you haven't told us whether nuget sends the right authentication info in response to challenge from servers. If we don't hear from you, then we'll close this issue.

@patrickjamesbarry
Copy link
Author

Sorry for delay. Yes, it does respond correctly to the challenge, but I question the need for this extra exchange, when the user has credentials already configured for the Source. Why would we not set PreAuthenticate? A failed response would result in the same response code, however, a successful exchange would result in the elimination of another back and forth exchange. Seems like this would just make nuget more efficient.

@feiling
Copy link

feiling commented Jun 8, 2015

Close this bug since @patrickjamesbarry has confirmed that authentication headers are sent by NuGet. Created issue #742 for the possible perf improvement.

@feiling feiling closed this as completed Jun 8, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority:2 Issues for the current backlog. Type:Bug
Projects
None yet
Development

No branches or pull requests

4 participants