I am trying to download a file from a C# application. I have tried two different methods, but both yield the same response: "The remote server returned an error: (401) Unauthorized."
I am pretty sure this is a credentials issue (because of the 401). If I navigate to the url from a browser, and enter the very same credentials provided, the file downloads just fine. In "Attempt 2" (below), for authtype, I have tried: NTLM, Basic, Negotiate, and Digest without any luck.
Does anyone see what I might be doing wrong here?
Thanks for the help!
Attempt 1:
string username = "username";
string password = "password";
string domain = "domain";
string url = @"http://LiveLinkInstance.com/livelink/llisapi.dll/999999/WordDocument.docx?func=doc.Fetch开发者_StackOverflow社区&nodeid=999999&ReadOnly=True&VerNum=-2&nexturl=/livelink/llisapi.dll?func=ll&objId=888888&objAction=browse&viewType=1";
// Create an instance of WebClient
WebClient client = new WebClient();
client.Proxy = null;
client.Credentials = new System.Net.NetworkCredential(username, password, domain);
client.DownloadFile(new Uri(url), @"C:\FileDownloads\test.txt");
Attempt 2:
string username = "username";
string password = "password";
string domain = "domain";
string url = @"http://LiveLinkInstance.com/livelink/llisapi.dll/999999/WordDocument.docx?func=doc.Fetch&nodeid=999999&ReadOnly=True&VerNum=-2&nexturl=/livelink/llisapi.dll?func=ll&objId=888888&objAction=browse&viewType=1";
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
string credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(domain + "\\" + username + ":" + password));
wr.Headers.Add("Authorization", "Basic " + credentials);
CredentialCache cc = new CredentialCache();
cc.Add(new Uri(url), "NTLM", new NetworkCredential(username, password, domain));
wr.Credentials = cc;
Stream str = ws.GetResponseStream();
As Amitay said, using fiddler to compare against traffic from browser is the best way to go. BTW, look here on SO - what's happening is OP's case was that request was getting redirected to different location but credentials were not re-passed. So OP did manual redirection to solve the issue.
Did you try
client.UseDefaultCredentials = true
if you are using MVC or WebApi you should decorate your method with
[Authorize]
If you are able to impersonate a user, use it like this
WindowsIdentity wi = null;
wi = (WindowsIdentity)HttpContext.Current.User.Identity;
using (wi.Impersonate())
{
var client = new WebClient { UseDefaultCredentials = true };
client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
var result = JsonConvert.DeserializeObject<Object>(Encoding.UTF8.GetString(client.DownloadData("http://api.com/api/values")));
return Request.CreateResponse(result);
}
I saw LL using its own form-based authentication or SSO based on IWA. I don't know if you can use other HTTP authentication types.
If your server uses the (default) form authentication you would have to use LAPI or WS to download the document providig the LL credentials within the LAPI/WS call. You could also just get a cookie for HTTP communication by LAPI/WS.
If you have SSO configured you can set Credentials to CredentialCache.DefaultCredentials to pass in credentials of the currently authentified Windows session.
精彩评论