HttpWebRequest with GET: 401 unauthorized - c#

I found some problem with httpWebRequest, I've read all the same issues on other forums, but answers don't seem to work. My code:
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse resp;
wr.ContentType = "text/html; charset=UTF-8";
wr.Method = "GET";
wr.Credentials = new NetworkCredential("user", "password");
resp = (HttpWebResponse)wr.GetResponse();
The remote server returned an error: (401) Unauthorized.
Response says there's no auth token in cookies. I can receieve this token using my auth request with POST method. I even tried to put it to CookieContainer by "new Cookie ("authToken",token_value)". But the result is the same - error 401. Does anybody know the solution?
Thanx.
I use Zimbra web server, have an access to control it. .NET 4.0. My url is the path to .eml file I need to download. To specify the file I need to add some GET parameters: id and part. So the whole address looks like http://someserver.info/service/content/get?id=1&part=1

(Answered in the comments and question edits by OP. Moved here. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
The authorization token in Zimbra called ZM_AUTH_TOKEN so you need to put your authtoken in cookies like this:
wr.CookieContainer = new CookieContainer();
wr.CookieContainer.Add(new Uri(url), new Cookie("ZM_AUTH_TOKEN", rc.AuthToken));
You don't need to put the auth headers then, the request will work

Related

Yelp Fusion API v3 returns 401 Unauthorized with TOKEN_MISSING error when called from c#

I've created my app in Yelp, got my api key, and things work fine from Postman when executing a business search.
However, when testing from c#, I receive a 401 unauthorized error with a TOKEN_MISSING error that says ""{\"error\": {\"code\": \"TOKEN_MISSING\", \"description\": \"An access token must be supplied in order to use this endpoint.\"}}"".
I'm supplying my api key correctly though, and the Yelp documentation says that's all I need, so I'm not sure what the problem is. Here are 2 separate c# code samples that do NOT work (I've replaced my actual api key with for security concerns):
Example using WebRequest:
var webRequest = WebRequest.Create("http://api.yelp.com/v3/businesses/search?term=Clayton+Bicycle+Center&location=5411+Clayton+Rd%2c+Clayton%2c+CA+94517%2c+US");
webRequest.Method = "GET";
webRequest.Headers.Add("Cache-Control", "no-cache");
webRequest.Headers.Add("Authorization", "Bearer <my_api_key>");
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
var stream = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8);
var content = stream.ReadToEnd();
Console.Write(content);
Example using RestSharp:
var client = new RestClient("http://api.yelp.com/v3/businesses/search?term=Clayton+Bicycle+Center&location=5411+Clayton+Rd%2c+Clayton%2c+CA+94517%2c+US");
var request = new RestRequest(Method.GET);
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Authorization", "Bearer <my_api_key>");
var response = client.Execute(request);
Console.Write(response.Content);
I've examined the requests in Fiddler, and both are sending the same headers as the working Postman search, but both return 401 unauthorized error while Postman returns the search results. Any ideas?
Edit:
Well this is embarrassing, apparently my issue was I was attempting to access the Yelp API via http instead of https. Once I changed to https, everything worked as expected.
Changed endpoint to use https instead of http, works now.

HTTP GET works in browser, but doesn't with HTTPWebRequest

Title explains it. I am trying to change the password of a webpage programmatically using HTTP Web Request. When I do it through Google Chrome (pasting the uri in the address bar), the password change works. Here is the header I get when I inspect in Chrome.
Remote Address:10.160.70.55:443
Request URL:https://10.160.70.55/cgi-bin/check_user.cgi?Type=basic&Current=78-62-118-112-106-108-56&Password=98-96-102-96-106-96
Request Method:GET
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,fr;q=0.6,ar;q=0.4
Authorization:Digest username="admin", realm="Secure Access", nonce="f3c6fcd9a549a42e9aac22818cb0f5ad", uri="/cgi-bin/check_user.cgi?Type=basic&Current=78-62-118-112-106-108-56&Password=98-96-102-96-106-96", response="cd17523a279f044d086b5bd0245eda0e", qop=auth, nc=0000001b, cnonce="9bd719c27efd9721"
Connection:keep-alive
Host:10.160.70.55
When I try to do it programatically, I receive the OK (200) code, but the password change does not work. Here's my code.
System.Uri uri2 = new Uri(string.Format("https://{0}/cgi-bin/check_user.cgi?Type=basic&Current=78-62-118-112-106-108-56&Password=98-96-102-96-106-96", ip));
HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(uri) as HttpWebRequest;
request2.Accept = "text/html";
request2.Credentials = new NetworkCredential("admin", "M#ster1");
request2.Method = WebRequestMethods.Http.Get;
HttpWebResponse response2 = (HttpWebResponse)request.GetResponse();
WriteLog(response2.StatusDescription.ToString());
response2.Close();
Used fiddler as suggested, and it turns out it was the user-agent header. And thank you for correcting the typo L.B. :)

Weird paypal api issue

I just started using the Paypal API and I'm stuck on this problem.
I generate a paypal request in code and when I send it I get back the following.
TIMESTAMP=2011-05-16T01:26:37Z
CORRELATIONID=6d4327d15421f
ACK=Failure
L_ERRORCODE0=10001
L_SHORTMESSAGE0=Internal Error
L_LONGMESSAGE0=Timeout processing request
When I run through the debugger and copy the generated request url and paste it into my web browser, I get a success response....
I'm sending the request like this - c#
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
WebResponse response = req.GetResponse();
The same request, but one sent by code, and one copied to the browser produces to different results. Why is that?
I got same problem. When remove the
request.Method ="POST";
line, problem is solved.

C# REST client sending data using POST

I'm trying to send a simple POST request to a REST web service and print the response (code is below, mostly taken from Yahoo! developer documentation and the MSDN code snippets provided with some of the documentation). I would expect the client to send:
Request Method: POST (i.e. I expect $_SERVER['REQUEST_METHOD'] == 'POST' in PHP)
Data: foo=bar (i.e. $_POST['foo'] == 'bar' in PHP)
However, it seems to be sending:
Request Method: FOO=BARPOST
Data: (blank)
I know the API works as I've tested it with clients written in Python and PHP, so I'm pretty sure it must be a problem with my C#. I'm not a .NET programmer by trade so would appreciate any comments/pointers on how to figure out what the problem is - I'm sure it's something trivial but I can't spot it myself.
uri, user and password variables are set earlier in the code - they work fine with GET requests.
request = (HttpWebRequest) WebRequest.Create(uri);
request.Credentials = new NetworkCredential(user, password);
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "application/x-www-form-urlencoded";
string postData = "foo=bar";
request.ContentLength = postData.Length;
StreamWriter postStream = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
postStream.Write(postData);
postStream.Close();
response = (HttpWebResponse) request.GetResponse();
The REST API is written in PHP, and the $_POST array is empty on the server when using the C# client.
Eventually found the HttpWebRequest.PreAuthenticate property which seems to solve the problem if the code is edited like so:
request = (HttpWebRequest) WebRequest.Create(uri);
request.PreAuthenticate = true;
request.Credentials = new NetworkCredential(user, password);
request.Method = WebRequestMethods.Http.Post;
From the documentation I presume this forces authentication before the actual POST request is sent. I'm not sure why the class doesn't do this automatically (libraries for other languages make this process transparent, unless you explicitly turn it off), but it has solved the problem for me and may save someone else another 2 days of searching and hair-pulling.
For what it's worth, PreAuthenticate doesn't need to be set for GET requests, only POST, although if you do set it for a GET request everything will still work, but take slightly longer.

Cannot handle redirect from HTTP/HTTPS protocols to other dissimilar ones

Basically, I'm trying to grab an EXE from CNet's Download.com
So i created web parser and so far all is going well.
Here is a sample link pulled directly from their site:
http://dw.com.com/redir?edId=3&siteId=4&oId=3001-20_4-10308491&ontId=20_4&spi=e6323e8d83a8b4374d43d519f1bd6757&lop=txt&tag=idl2&pid=10566981&mfgId=6250549&merId=6250549&pguid=PlvcGQoPjAEAAH5rQL0AAABv&destUrl=ftp%3A%2F%2F202.190.201.108%2Fpub%2Fryl2%2Fclient%2Finstaller-ryl2_v1673.exe
Here is the problem: When you attempt to download, it begins with HTTP, then redirects to an FTP site. I have tried .NET's WebClient and HttpWebRequest Objects, and it looks like Neither can support Redirects.
This Code Fails at GetResponse();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://dw.com.com/redir");
WebResponse response = req.GetResponse();
Now, I also tried this:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://dw.com.com/redir");
req.AllowAutoRedirect = false;
WebResponse response = req.GetResponse();
string s = new StreamReader(response.GetResponseStream()).ReadToEnd();
And it does not throw the error anymore, however variable s turns out to be an empty string.
I'm at a loss! Can anyone help out?
You can get the value of the "Location" header from the response.headers, and then create a new FtpWebRequest to download that resource.
in your first code snippet you will be redirected to a link using a different protocol (i.e it's no longer Http as in HttpWebRequest) so it fails du to a malformed http response.
In the second part you're no longer redirected and hence you don't receive a FTP response (which is not malform when interpreted as HTTP response).
You need to acquire FTP link,as ferozo wrote you can do this by getting the value of the header "location", and use a FtpWebRequest to access the file

Categories

Resources