HTTPWebRequest returns 401 unauthorized - c#

I make a POST HTTPWebRequest to an URL to download a file. The problem is request fails with message authentication failed. But the same request made via POSTMAN app works fine. Error I receive is :
The remote server returned an error: (401) Unauthorized. Protocol Error.
The fiddler capture of requests between the two shows that POSTMAN has few additional ciphers, ec_point_formats, elliptic_curves, signature_algs. Not sure if that matters but in the interest of keeping this post short I am not giving the actual differences but can provided if asked for.
Sample code I use:
// create a request
HttpWebRequest request; = (HttpWebRequest)WebRequest.Create(inputUri);
SetProxy(inputProxyUri, inputProxyUser, inputProxyPassword, request);
request.ProtocolVersion = HttpVersion.Version11;
//Set authorization
string authorisation = string.Format("{0}:{1}", user, pass);
string encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(authorisation));
string header = string.Format("{0} {1}", "Basic", encoded);
request.Headers[HttpRequestHeader.Authorization] = header;
request.KeepAlive = false;
request.Method = "POST";
byte[] postBytes = Encoding.ASCII.GetBytes(requestParams);
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
//Get response stream
System.IO.Stream responseStream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
I have played with request object mentioned below :
request.ProtocolVersion = HttpVersion.Version11;
request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequired;
request.UseDefaultCredentials = true;
request.PreAuthenticate = true;
request.Credentials = CredentialCache.DefaultCredentials;
request.Accept = "*/*";
Also changed registry to enable TLS 1.2, enable TLS-1.2 for client and server SCHANNEL communications as mentioned in https://www.derekseaman.com/2010/06/enable-tls-12-aes-256-and-sha-256-in.html without much luck.
Any help would be appreciated.

Related

Jenkins ERROR 403 No valid crumb was included in the request - using github authentication

Recently I upgraded from a very old jenkins version from 2016 to 2.289.1. I updated all the plugins as well. Previously we had it setup with github security. When we would send jobs, it would be sent with the username and oauth key generated from github, and that's how we would track who sent jobs.
After upgrading, every time I would try to send a job I would get HTTP ERROR 403 No valid crumb was included in the request. I've tried a lot of different solutions I found online, like checking Enable proxy compatibility under crsf protection, or downloading the crumb plugin. I even started requesting the crumb and attaching it to the header. In all cases I was still getting the crumb error.
Now if I disabled the github authentication and changed it to jenkins own user database, and replaced the username and token with a jenkins one (and kept the code to insert the crumb into the header) then the job would successfully get sent to jenkins. I would rather do it through github since that is how we have it setup, anyone have any suggestions now how to get around the crumb error?
here is just a piece of the code that sends the request
HttpWebRequest crumbRequest = WebRequest.Create(jenkinsCrumbUrl) as HttpWebRequest;
crumbRequest.Method = "GET";
HttpWebResponse crumbResponse = (HttpWebResponse)crumbRequest.GetResponse();
StreamReader responseReader = new StreamReader(crumbResponse.GetResponseStream());
string responseString = responseReader.ReadToEnd();
var crumb = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseString);
HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = contentType;
request.UserAgent = userName;
request.CookieContainer = new CookieContainer();
request.ContentLength = formData.Length;
request.PreAuthenticate = true;
byte[] credentialBuffer = new UTF8Encoding().GetBytes(String.Format("{0}:{1}", userName, APIToken));
request.Headers["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(credentialBuffer));
request.Headers[crumb["crumbRequestField"]] = crumb["crumb"];
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(formData, 0, formData.Length);
requestStream.Close();
}
return request.GetResponse() as HttpWebResponse;

HTTP error 403 if POST is not used

I am trying to send protobuf data via REST from c# winform application. When I use the HTTP request with POST method( as shown in code below) it works perfect and returns "OK" status.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://xxxxx.execute-api.eu-west-1.amazonaws.com/test/input");
request.Headers["Authorization"] = "xxxyyyzzz"
request.Method = "POST";
request.ContentType = "application/octet-stream";
byte[] bytes = System.IO.File.ReadAllBytes("C:\\MyProtobuf.proto");
request.ContentLength = bytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
HttpWebResponse myHttpWebResponse = (HttpWebResponse)request.GetResponse();
MessageBox.Show(myHttpWebResponse .StatusCode.ToString());
myHttpWebResponse .Close();
But if I simply want to check if website is alive or not using below code it gives me 403. Forbidden error.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://xxxxx.execute-api.eu-west-1.amazonaws.com/test/input");
request.Headers["Authorization"] = "xxxyyyzzz";
HttpWebResponse myHttpWebResponse = (HttpWebResponse)request.GetResponse();
MessageBox.Show(myHttpWebResponse .StatusCode.ToString());
myHttpWebResponse .Close();
what could be the possible reason for this error ?
your services serves POST method verb so you must call this service with post method, otherwise you should change your service methods to support get method.

Getting 401 Unauthorized error on file upload

I have an asp.net application that submits files to a sharepoint document library.
Each time it tries to submit I get a
The remote server returned an error: (401) Unauthorized
Here is the c# code
byte[] buffer = new byte[length];
postedFile.InputStream.Read(buffer, 0, length);
Uri address = new Uri(url);
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.UseDefaultCredentials = true;
request.Accept = "application/json;odata=verbose";
request.Headers.Add("X-RequestDigest", dvalue);
request.ContentType = "application/json; charset=utf-8";
request.ContentLength = length;
using (Stream postSTream = request.GetRequestStream())
{
postSTream.Write(buffer, 0, length);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
}
This works fine on my local machine, but when I deploy it to our test environment, it raises the 401 error. IIS is configured for anonymous authentication. I think it is something to do with the file upload? Any insight or thoughts are appreciated!
Thanks
You should give write folder permission to the applicaion pool user account.

request.GetResponse(); returns 407 (Proxy Authentication Required) even though correct credentials are supplied

I'm developing an application (in C#) which sends http requests.
Everything works fine as long as there's no Proxy with authentication involved.
Here's my code:
request = (HttpWebRequest) WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = length;
request.Proxy.Credentials = new NetworkCredential("hans", "maulwurf");
request.Credentials = new NetworkCredential("hans", "maulwurf");
using (var requestStream = request.GetRequestStream())
{
// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Flush();
requestStream.Close();
}
WebResponse webResponse = request.GetResponse();
On the last line i always get 407. The credentials work in ie/ff.
Does anyone have suggestions what the problem might be?
Any help is greatly appreciated!
I think you may need to also specify the proxy server. like this, for example,
IWebProxy proxy = new WebProxy("<Server IP>", <Server Port>);
proxy.Credentials = new NetworkCredential("hans", "maulwurf");
request.Proxy = proxy;

ASP HttpWebRequest and Redirect

OK, I have a client doing a POST to a server with some data. The server receives the post, and answers with a redirect. The problem is that the client does not redirects. Also, I've tried to check the StatusCode of the response the client gets, and it is always the same "OK". Instead of the redirect code. What am I missing?
In the client side I have something like this:
StringBuilder sb;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost/serv/Default.aspx");
request.Method = "POST";
byte[] data = Encoding.ASCII.GetBytes(GetDATA());
request.ContentType = "text/xml";
request.ContentLength = data.Length;
Stream stream = request.GetRequestStream();
stream.Write(data, 0, data.Length);
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 10;
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
response.Close(); } catch(Exception ex) {}
In the server side I have just this line:
HttpContext.Current.Response.Redirect("http://www.google.com", true);
In this case, the client receives an answer and does not do nothing.
Thanks.
When you have "AllowAutoRedirect" set to true, it means that your HttpWebRequest object will make a 2nd webrequest once it sees a redirect. When you see the "200 OK" from the response object, it is because you are seeing the response for "www.google.com". You can check the Response.ResponseURI to verify this.
You'll need to turn off the "AllowAutoRedirect", then check the response code like Oded said.

Categories

Resources