There is a web file within my intranet that my computer is authorized to read and write. I can open up IE or Firefox and view the file by typing int the url address. I need to write a C# desktop app that reads/writes to that file. Even though my computer has access, all my attempts so far result in 401, unauthorized access errors. The program needs to work from any computer whose account has been authorized, so I cannot hard-code any username/password. I've never done anything like this, but I was able to scrounge the following from several sites:
WebRequest objRequest = HttpWebRequest.Create("https://site.com/file");
objRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
objRequest.Proxy = WebRequest.DefaultWebProxy;
objRequest.Proxy.Credentials = CredentialCache.DefaultCredentials;
WebResponse objResponse = (WebResponse)objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
string str = sr.ReadToEnd();
sr.Close();
//... Do stuff with str
}
If it matters, I'm working in .NET 2.0
Just ran into the same problem, it all started working when I added:
objRequest.UseDefaultCredentials = true;
Did you try using Fiddler to inspect the actual request that was sent to the server?
You can also check if the server requires a client certificate to allow the connection.
Since you are accessing an intranet server, do you really need to set the proxy part? I mean most of the time, the proxy is configured to ignore local addresses anyway.
This won't work if NTLM credentials are required:
objRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
You need to pass in the actual credentials like:
NetworkCredential networkCredential = new NetworkCredential(UserName, Password, Domain);
CredentialCache credCache = new CredentialCache();
credCache.Add(new Uri(url), "NTLM", networkCredential);
objRequest.Proxy.Credentials = credCache;
Related
I am trying to read a sharepoint site using HttpWebRequest, but the below code throws an exception (403 Forbidden):
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(#"https://myCompany.sharepoint.com/sites/it/abc/ScriptAttest/docs/");
r.Method = "GET";
WebResponse rs = r.GetResponse();
I get the same response if I add
client.Credentials = new NetworkCredential("username", "secret");
(using my domain credentials of course)
or specify default credentials.
However, if I create a browser control (called documentBrowser) and execute the following:
documentBrowser.Navigate(#"https://myCompany.sharepoint.com/sites/it/abc/ScriptAttest/docs/");
I get the data. However, it takes a long time, and I don't really need to display the page. My objective is to parse the html and only pull out certain elements. Additionally, the data comes in stages and the control triggers the DocumentCompleted event after each segment, so I don't really know when the entire page has loaded.
SharePoint Online does not support NetworkCredential. documentBrowser.Navigate in fact use the embed IE browser which may has some SPO related cache, thus it could navigate to the site. If you want to fetch data from SPO, you could use Rest API or CSOM. If you just want to access the site page, you may consider using cookie to get it:
var login = "admin#***.onmicrosoft.com";
var password = "P#ssw0rd";
var siteUrl = "https://***.sharepoint.com/";
var creds = new SharePointOnlineCredentials(login, password);
var auth = creds.AuthenticateAsync(new Uri(siteUrl), true);
var request = (HttpWebRequest)WebRequest.Create(siteUrl);
request.CookieContainer = auth.Result.CookieContainer;
var result = (HttpWebResponse)request.GetResponse();
BR
I have the following code:
using (WebClient wcli = new WebClient())
{
wcli.UseDefaultCredentials = true;
wcli.Credentials = new NetworkCredential("RS_Username", "RS_Password", "RS_Domain");
byte[] buff = wcli.DownloadData(www);
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + reportName + ".pdf\"");
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.BinaryWrite(buff);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
I use it get the result of a report in SSRS 2014 and have it as a document download from my web application (in .Net 3.5, hosted on Window 8.1, IIS 8.5).
The problem I have is that I keep getting 401 Unauthorized when calling wcli.DownloadData(www) (Note the using any browser the reports are working fine with the credentials used)
I have done a TCP Dump and I have found out that the NTLM handshake is not occurring:
C -> S: GET Request
C <- S: '401 Unauthorized' response with header
'WWW-Authenticate: NTLM'
Nothing else
Another application hosted on the same machine but using .Net 4.5 uses the same code without any problem.
I believe it has to be due to a missing/wrong configuration, but I do not succeed to figure out which one.
Any ideas?
UPDATE
What I have forgotten to mention is that both web applications mentioned (both hosted on the same server and IIS) are connecting to the same Reporting Services server (but different folders).
I have had the same issue, in my case (Still .Net4.5) what worked was to use:
WebClient wc = new WebClient();
wc.UseDefaultCredentials = false;
string host = "http://localhost"; //this comes from a function in my code
var myCredentialCache = new System.Net.CredentialCache();
myCredentialCache.Add(new Uri(host + "/"), "NTLM", new System.Net.NetworkCredential(accessUser, accessPassword, domain));
wc.Credentials = myCredentialCache;
var result = wc.DownloadFile(www);
The main diference for me was to use a CredentialCache and setting the host uri, also the domain in the network credential
You're telling the WebClient to use the DefaultCredentials. wcli.UseDefaultCredentials = true; but you're also passing in a NetworkCredential. Perhaps the other code that works, if they're both using the same code, is working because it's user has access.
using (WebClient wcli = new WebClient())
{
wcli.UseDefaultCredentials = true;
wcli.Credentials = new NetworkCredential("RS_Username", "RS_Password", "RS_Domain");
}
However, that may not be your bug. Came across this article: http://www.benjaminathawes.com/2010/10/14/ntlms-dependency-on-http-keep-alives-another-cause-of-the-dreaded-401-1-error/.
It mentions the need to use HTTP keep-alive to keep the TCP connection open for the NTLM handshake. The fact that the handshake just dies leads me to think that maybe that could also be the issue. I would check to verify that keep-alive is indeed on.
I am working on a project that uses proxy to obtain websites' HTML code.
Now, the trouble I have is that I want to use Username-Password authentication and not IP-Auth when connecting to the proxy.
I have written a sample code and ran it with Snippy. It worked. Then I copied the same code into a Visual Studio .NET 4.5 Project and it failed with the error: An existing connection was forcibly closed by the remote host when trying to get the response.
Here is the code:
WebProxy[] proxies = { new WebProxy("ip", port) };
proxies[0].Credentials = new NetworkCredential { UserName = "username", Password = "password" };
string url = "https://www.google.com/search?q=s&num=50";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Proxy = proxies[0];
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
{
using (StreamReader response_stream = new StreamReader(res.GetResponseStream())
{
string html = response_stream.ReadToEnd();
Console.WriteLine(html);
}
}
I have tried different variations. When I switch to authorization by IP, add mine and comment out the NetworkCredentials assignment, the code works perfectly both in Snippy and Visual Studio.
But why does it fail when using NetworkCredentials?
OK, I found the culprit. It was my proxy provider.
Note for everybody ever running into problems when testing proxy connection with HttpWebRequest -- try another seller. It might save you a couple of minutes. Or hours.
I have been using this code to read in a file from a document repository in sharepoint:
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create("http://servername/realestate/SiteAssets/navigation.txt");
objRequest.Timeout = 10000;
objRequest.UseDefaultCredentials = true;
objRequest.Proxy.Credentials = objRequest.Credentials;
objResponse = (WebResponse)objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
navBar = sr.ReadToEnd();
sr.Close();
}
I just migrated to a new environment, and I am getting a 401 unauthorized error with this code - but, instead of using servername, I am now using hostname (since the new environment has a domain assigned to it). How can I navigate this issue, even though I am now using a host in my HttpWebRequest object? And, if this should not be causing the issue, I would like to hear recommendations as well. Thanks.
Local Loopback check?
KB 896861 - You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or a later version
I'm currently developing an IE plugin using SpicIE.
This plugin does some web scraping similar to the example posted on MSDN:
WebRequest request = WebRequest.Create ("http://www.contoso.com/default.html");
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
Stream dataStream = response.GetResponseStream ();
StreamReader reader = new StreamReader (dataStream);
string responseFromServer = reader.ReadToEnd ();
reader.Close ();
dataStream.Close ();
response.Close ();
However, when i run this code i receive the following error message:
The remote server returned an error: (407) Proxy Authentication Required.
I'm currently working behind a proxy server and used the NetworkCredential class to manually provide my network credentials
request.Credentials = new System.Net.NetworkCredential("name", "password", "domain");
but i still receive the same error.
Even if my problem is solved, i know that some users of the plugin will be behind a proxy server.
I want to know how i can get IE credentials and use it in my code to assign it to request.Credentials.
Maybe something like this:
request.Credentials = IE.DefaultCredentials;
You're setting the credentials for the site, but you need credentials for the proxy.
Set request.Proxy.Credentials.
(Also, use using statements for the response/stream/reader rather than manually closing them, otherwise they'll leak when an exception is thrown.)
EDIT: For instance, to use the default credentials for the proxy as well:
request.Proxy.Credentials = CredentialCache.DefaultCredentials;