C# basic pre-emptive authentication - c#

I need to consume web service that requires basic pre-emptive authentication. I have below code, but getting an error on response -
'The remote server returned an error: (403) Forbidden.'
User credentials are correct. Any ideas what is wrong?
string url = "MYURL";
HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest;
string user = "USER";
string pwd = "PASSWORD";
string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(user + ":" + pwd));
req.PreAuthenticate = true;
req.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
req.Headers.Add("Authorization", auth);
WebResponse resp = req.GetResponse();
resp.Close();
req = HttpWebRequest.Create(url) as HttpWebRequest;
req.PreAuthenticate = true;
req.Credentials = new NetworkCredential(user, pwd);
resp.Close();

401 is the error code you receive when you could not be authenticated (i.e. it's unclear who you are). If you get a 403 that means the server knows who you are but still thinks you should not be allowed access.
I guess you should talk to whoever provided you with the credentials and ask him.

Related

400 vs 401 http responses : which one is evaluated/returned first?

I have been trying to make a post request with C# using Webclient. I was getting 400 bad request.When I adjusted the headers, and added authorization to it,I started getting 401 authorization error.Now i commented out the authorization, 400 bad request is back. So my question is: when it was returning 400, does it mean the server authenticated me and that something might be wrong with my json or can 400 be returned even before authentication is done? Below is my code.
public static string Post(string json, string encoded){
try{
string url = "https://blah/rest/api/blah";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var client = new WebClient();
client.Encoding = Encoding.UTF8;
IWebProxy wp = WebRequest.DefaultWebProxy;
wp.Credentials = CredentialCache.DefaultCredentials;
client.Proxy = wp;
//client.Headers[HttpRequestHeader.Authorization] = "Basic " + encoded;
client.Headers[HttpRequestHeader.ContentType] = "application/json";
client.Headers[HttpRequestHeader.Accept] = "application/json";
var response = client.UploadString(url, "POST",json);
return response
}
catch(Exception e){
return e
}
}

I am trying to consume data from the Avaya office manager API. CertificateValidationCallback causing error

My error is
The request was aborted: Could not create SSL/TLS secure channel.
I am using the example code from the Avaya office management api documentation.
I can't get CertificateValidationCallback to compile.
protected void Page_Load(object sender, EventArgs e)
{
ServicePointManager.ServerCertificateValidationCallback = new
System.Net.Security.RemoteCertificateValidationCallback(CertificateValidationCallback);
String username = "";
String password = "";
String url = "https://10.207.251.41:7070/WebManagement/ws/sdk/security/authenticate";
CookieContainer cookieContainer = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "GET";
request.ContentType = "application/json";
request.Headers.Add("X-User-Client", "Avaya-WebAdmin");
request.Headers.Add("X-User-Agent", "Avaya-SDKUser");
String credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + credentials);
request.CookieContainer = cookieContainer;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var resStream = response.GetResponseStream();
var reader = new StreamReader(resStream);
String responseContent = reader.ReadToEnd();
response.Close();
}
If the certificate is not trusted by Certification Authority (and I don't think so because of the request, but it sounds instead like a test certificate), you shall install it on your system as trusted by MMC console, adding "certificate" snap/in, selecting your local pc as destination. Then, in the snap in shall appear a list of certificate folders, find the "trusted root certificates" and import the certificate (if you don't have it, I think that you can download it with the browser visiting the link https://10.207.255.45:7070 ). Once it's installed there, this could fix your problem

HTTPWebRequest returns 401 unauthorized

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.

How can I access SharePoint 2010 site page which has claim based authentication through windows application?

I need to create a windows application which will access SharePoint 2010 site page to stote that page in ".htm" format in local drive.
But, that SharePoint site has claim based authentication.
For accessing that site I have to provide "Username" & "Password" along with "Domain name".
So, I need help on how can I pass site credentials through windows application to get access into that site??
I have used following code but this throws exception "The remote server returned an error: (403) Forbidden".
WebRequest Request1;
HttpWebResponse Response1;
Request1 = WebRequest.Create(txtUrl.Text.ToString());
Request1.Credentials = new NetworkCredential(strUserNm.ToString(), strPassword.ToString(), StrDomain.ToString());
Request1.PreAuthenticate = true;
Response1 = (HttpWebResponse)Request1.GetResponse();
Any help will be appreciable...
Based on Warmup timer job with dual authentication mode, I changed this:
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
request.Timeout = System.Threading.Timeout.Infinite;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
WebResponse response = request.GetResponse();
to this:
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.Timeout = System.Threading.Timeout.Infinite;
request.Credentials = new CredentialCache
{
{ new Uri(url), "NTLM", new NetworkCredential(username, password, domain) }
};
request.Headers.Add("Authorization", GetAuthorization(username, password, domain));
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 GTB7.1 ( .NET CLR 3.5.30729)";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.CookieContainer = new CookieContainer();
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
The GetAuthorization method looks like this:
private function GetAuthorization(string username, string password, string domain)
{
string credentials = string.Format(#"{0}\{1}:{2}", domain, username, password);
byte[] bytes = Encoding.ASCII.GetBytes(credentials);
string base64 = Convert.ToBase64String(bytes);
return = string.Concat("NTLM ", base64);
}
With the updated code, I was able to access files in both Classic and Claims Based web applications.
Pay attention to how the domain is being captured..
//Do not use domain\username or username#domain for the username
parameter of this constructor. This will not work (by design). The
constructor that takes a domain has 3 arguments. Or use the domain
property as clearly documented in the sample code above.
// Call the onstructor to create an instance of NetworkCredential with the
// specified user name and password.
NetworkCredential myCredentials = new NetworkCredential(username,passwd);
// Create a WebRequest with the specified URL.
WebRequest myWebRequest = WebRequest.Create(url);
myCredentials.Domain = domain;
myWebRequest.Credentials = myCredentials;
Console.WriteLine("\n\nCredentials Domain : {0} , UserName : {1} , Password : {2}",
myCredentials.Domain, myCredentials.UserName, myCredentials.Password);
Console.WriteLine("\n\nRequest to Url is sent.Waiting for response...");
// Send the request and wait for a response.
WebResponse myWebResponse = myWebRequest.GetResponse();
// Process the response.
Console.WriteLine("\nResponse received successfully.");
// Release the resources of the response object.
myWebResponse.Close();

C# .Net 2.0 ResponseUri.Query empty

I have a problem when I do an httprequest and the remote server responds with a redirect and some additional query parameters. The problem is that the additional parameters is empty on certain enviroments.
When I run the code in a test-environment the parameters is not empty.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
WebProxy myProxy = new WebProxy();
Uri newUri = new Uri(ConfigurationManager.AppSettings["proxyUrl"]);
myProxy.Address = newUri;
request.Proxy = myProxy;
request.Timeout = Int32.Parse(ConfigurationManager.AppSettings["PBVtimeout"]);
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 2;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(myCertificateValidation);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
log.Debug("PathAndQuery: " + response.ResponseUri.PathAndQuery);
log.Debug("Statuscode: " + response.StatusCode);
log.Debug("Statusdescription: " + response.StatusDescription);
Uri uri = response.ResponseUri;
NameValueCollection qscol = ParseQueryString(uri.Query);
return qscol["Status"] + qscol["Status_code"];
I log StatusCode, StatusDescription and the PathAndQuery of the response. StatusCode and StatusDescription is "OK" in both enviroments but the PathAndQuery looks like this:
Faulty environment: localhost/Service
Correct environment: localhost/Service?Merchant_id=1345&Version=2&Customer_refno=269932&Status=E&Status_code=48
As you can see the faulty enviroments is missing the parameters.
My initial thought was that it was a problem with a firewall "cleaning" the redirect response. But when I did the http request in an ordninary web browser it worked fine.
The code is in C# .Net 2.0 and it runs on a Windows 2003 server.
Any ideas where the problem could be?

Categories

Resources