Cannot connect to url in C# with 401 unauthorized error - c#

I'm looking to get the content of a page from
http://12.18.60.199:81
I'm using my corporate network and if I use internet explorer, it prompts for username and password, I type that in and I get the content of the page. I need to do this in C#, but have no luck for the past few hours:
Uri requestUri = null;
Uri.TryCreate("http://12.18.60.199:81", UriKind.Absolute, out requestUri);
NetworkCredential nc = new NetworkCredential(#"username", #"password", "domain");
CredentialCache cache = new CredentialCache();
cache.Add(requestUri, "Basic", nc); //also tried "Anonymous", "Basic", "Digest", "Dpa",
//"External", "Kerberos", "Msn", "Negotiate", "Ntlm", "Sicily"
using (WebClient client = new WebClient())
{
client.Credentials = cache;
using (Stream stream = client.OpenRead("http://12.18.60.199:81"))
using (StreamReader reader = new StreamReader(stream))
{
//stuff
}
}
Keep getting 401 unauthorized, invalid credentials, help!
If I substitute the above address with http://google.com, it'll work, so the code works... username and password have been tested to work in broswer

If you are connecting through a proxy server try adding in your proxy and pass the credentials. For example:
// Prepare web request...
HttpWebRequest myRequest =
(HttpWebRequest)WebRequest.Create("http://www.test.com");
// proxy details
myRequest.Proxy = new WebProxy("http://10.0.0.1", true);
myRequest.Proxy.Credentials = new NetworkCredential("test", "password", "domain");

I had same issue, and found workaround to add Authorization request header. I've used fiddler to get that base64. Never found proper solution, as you all know temp solutions are long-lasting in out world :)
service.Url = "http://127.0.0.1/";
service.SetRequestHeader("Authorization", "Basic dW8sX3NvYXB6SjRma2pzdXZqNDg5ZA==");
service.PreAuthenticate = true;

Related

Check credential before requesting the Web Service

For a WebService, How can I check the credential before requesting the WebService?
In this exemple we are using a bad password to simulate a HTTP 401 : Unauthorized..
Is there a way before the var param = DoComplexeWork(); to validate the credential?
string UserName = "FOOBAR_USR";
string SecurelyStroredPassword = "FOOBAR_BAD_PWD";
string Domain = "FOOBAR_DOM";
string Url = "https://example.com/Foo/Bar.svc";
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(
new Uri(Url),
"Basic",
new NetworkCredential(UserName, SecurelyStroredPassword, Domain)
);
var iFoo = new MyFooBarWebService();
iFoo.Credentials = credentialCache;
//Check if Credential is OK
var param = DoComplexeWork();
var result = iFoo.CreateBar(param);
Validating the credentials are made on each request. So you need another URL to request that only validates the credentials.
Depending on your webservice you might be able to make a HEAD request. But that may or may not trigger the actual processing as well.
So there is no obvious easy way to do this, because of the underlying HTTP protocol.

Get file list from owncloud

I want to get file list from owncloud on my ASP site. I was succeed using
curl -X PROPFIND -u user:password "http://yourserver.com/owncloud/remote.php/webdav/" from linux but I can't get the same result using default http request with propfind type in order to use it then in c# https://user:password#host/owncloud/remote.php/webdav. I get 400 code as a result on my request. Also I tried webdavclient from nuget but received method not allowed exception.
IClient c = new Client(new NetworkCredential { UserName = "user", Password = "password" });
var client = new WebDAVClient.Client(new NetworkCredential());
c.Server = "xxx.com/owncloud/remote.php/webdav/";
var isfolderCreated = c.CreateDir("/", "lalala").Result;
Could anybody say to me how to send http request to owncloud to get the file list? I tried webdav protocol that is used by clients but maybe I should try anything else?
I found the issue that prevented me. I just didn't use basic authorization correctly in http request. Since I add correct credentials I could send the http request and get the response. And here is the code I use in c#:
var request = (HttpWebRequest)WebRequest.Create("xxx.com/owncloud/remote.php/webdav/");
request.Credentials = new NetworkCredential("user", "password");
request.PreAuthenticate = true;
request.Method = #"PROPFIND";
request.Headers.Add(#"Translate", "F");
var httpGetResponse = (HttpWebResponse)request.GetResponse();
using (var responseStream = httpGetResponse.GetResponseStream())
{
long responseLength = httpGetResponse.ContentLength;
using (var streamReader = new StreamReader(responseStream, Encoding.UTF8))
{
var files = XElement.Parse(streamReader.ReadToEnd());
streamReader.Close();
}
responseStream.Close();
}

Posting Credentials to a basic authorization site and opening the link in a new browser. Open URL instead of a response

The below code will post a request to an IIS basic authorization site. And sucessfully log in to the site using Windows Credentials. But what I need to do is convert this to opening the website in a browser much like opening a new hyperlink with a target="null".
So just a recap, how do you post the WebRequest to a new browser tab? Or how do you send the CredentialCache to a new URL request?
var request = WebRequest.Create(testURL);
SetBasicAuthHeader(request, "username", "password", testURL);
var response = request.GetResponse();
}
public void SetBasicAuthHeader(WebRequest request, String userName, String userPassword, String testURL)
{
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new System.Uri(testURL), "Basic", new NetworkCredential(userName, userPassword, "domain"));
request.Credentials = credentialCache;
request.PreAuthenticate = true;
}
The short answer is, you can't send a response to a new tab. The problem with what you are trying to do is that the request / response that you build on the server is technically the server's...not the client. So even if you build the request and redirect the user to the URL you just authenticated to, the client is still considered unauthenticated because the authentication took effect on the server.

How can I read a secure XML URI in C#?

I am trying to read a secure XML document from a URI in C#. I understand the basics of the XmlReader class. However I cannot figure out how to supply a username and password for the URI in code. I get the feeling it has something to do with an XmlSecureResolver object. But I can't figure out how to set the username and password. Can anyone help me with how to set the credentials?
Thanks,
Corey
I think this should do the trick:
WebRequest request = WebRequest.Create(url);
request.Credentials = new NetworkCredential("usernamne", "password");
using (WebResponse response = request.GetResponse())
{
using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
{
// Blah blah...
}
}
A quick Google of the term "XmlReader Authenticate" yields this as the first result:
http://msdn.microsoft.com/en-us/library/47as68k4%28v=vs.71%29.aspx
When resolving a URL to a file that contains the XML data to read, the file may have a restricted access policy. If authentication is required to access a network resource, use the XmlResolver.Credentials property to specify the necessary credentials. If the XmlResolver.Credentials property is not set, then credentials are set to null.
XmlTextReader rdr = new XmlTextReader("http://localhost/bookstore/books.xml");
rdr.XmlResolver.Credentials = CredentialCache.DefaultCredentials;
XmlDocument doc = new XmlDocument();
doc.Load(rdr)
and using different credentials:
NetworkCredential myCred = new NetworkCredential(UserName, SecurelyStoredPassword, domain);
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri("www.contoso.com"), "Basic", myCred);
myCache.Add(new Uri("app.contoso.com"), "Basic", myCred);
reader.XmlResolver.Credentials = myCache;

Trouble downloading a file

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&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.

Categories

Resources