I use this code to get web content but get exception at WebResponse myResponse = myRequest.GetResponse();
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("https://www.ecfr.gov");
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate (Object obj, X509Certificate X509certificate, X509Chain chain, System.Net.Security.SslPolicyErrors errors)
{
return true;
};
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
StreamReader sr = new System.IO.StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
string result = sr.ReadToEnd();
sr.Close();
myResponse.Close();
I know it needs SSL/TLS Certificate, but I want to know why I still get an error?
https://www.ecfr.gov
Try this
static void Main(string[] args)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
var client = new HttpClient();
var result = client.GetAsync("https://www.ecfr.gov").Result;
var str = result.Content.ReadAsStringAsync().Result;
}
Related
When I test the api using console program works fine, but when I tried to do using a azure funtion this fail and I have error "Host lock lease acquired by instance ID 000000"
X509Certificate2 SenseCert = new X509Certificate2("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\client.pfx");
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
//Create the HTTP Request and add required headers and content
string xrfkey = "0123456789abcdef";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(#"https:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=" + xrfkey);
request.Method = "POST";
request.Accept = "application/json";
request.Headers.Add("X-xxxxxxx", xrfkey);
request.Headers.Add("Content-Type", "application/json");
// Add the certificate to the request and provide the user to execute
request.ClientCertificates.Add(SenseCert);
request.Headers.Add("X-xxxxxxxxx", #"UserXXXXXXXXX=internal;UserId=sadasdasdsad");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
Console.WriteLine(new StreamReader(stream).ReadToEnd());
And my function azure program
[FunctionName("CreateShoppingCartItem")]
public async Task<IActionResult> CreateShoppingCartItems(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "shoppingcartitem")] HttpRequest req,
ILogger log)
{
log.LogInformation("Creating Shopping Cart Item");
X509Certificate2 SenseCert = new X509Certificate2("client.pfx");
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
string xrfkey = "0123456789abcdef";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(#"https:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=" + xrfkey);
httpWebRequest.Method = "POST";
httpWebRequest.Accept = "application/json";
httpWebRequest.Headers.Add("X-xxxxxxx", xrfkey);
httpWebRequest.Headers.Add("Content-Type", "application/json");
httpWebRequest.ClientCertificates.Add(SenseCert);
httpWebRequest.Headers.Add("X-xxxxxxxxx", #"UserXXXXXXXXX=internal;UserId=sadasdasdsad");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
log.LogInformation(result);
}
return new OkObjectResult("ok");
}
Then I use a cert pfx to authenticate. How do that using azure function.
I have the error when I call post method
I have a script dat i want to convert to modern authentication. I cant find the right properties to do it. Could you help me?
HttpRequestCachePolicy policy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default);
HttpWebRequest.DefaultCachePolicy = policy;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);
HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
request.CachePolicy = noCachePolicy;
request.Method = "GET";
string encoded = "username:password";
request.Headers.Add("Authorization", "Basic " + encoded);
request.ContentType = "application/xml";
request.Headers["x-api-key"] = "12312312-1234-1234-1234-123123123123";
ServicePointManager.ServerCertificateValidationCallback = delegate (
Object obj, X509Certificate certificate, X509Chain chain,
SslPolicyErrors errors)
{
return (true);
};
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
string responseStr = new StreamReader(responseStream).ReadToEnd();
Console.WriteLine(responseStr);
return responseStr;
}
}
catch (Exception e)
{
Task.Run(() =>
{
});
}
I probaly need something like ConfidentialClientApplicationBuilder but i cant seem to find how to do it.
I am trying to get new token from channeladvisor ecommerce
I am using this code
// HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.channeladvisor.com/oauth2/token");
var request=HttpWebRequest.Create("https://api.channeladvisor.com/oauth2/token");
WebResponse response = null;
string responseString = string.Empty;
try
{
// request.Timeout = 300000;
// request.KeepAlive = false;
//request.ContentType = "application/json";
request.UseDefaultCredentials = true;
string credentials = applicationid + ":" + sharesecret;
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(credentials);
string base64 = Convert.ToBase64String(bytes);
request.Headers["Authorization"] = "Basic " + base64;
request.ContentType = " application/x-www-form-urlencoded";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
request.Method = "Post";
// var stringContent = new StringContent("grant_type=refresh_token&refresh_token=" + refreshToken);
request.ContentLength = System.Text.Encoding.ASCII.GetByteCount("grant_type=refresh_token&refresh_token=" + refreshToken);
byte[] buffer = System.Text.Encoding.ASCII.GetBytes("grant_type=refresh_token&refresh_token=" + refreshToken);
// string result = System.Convert.ToBase64String(buffer);
Stream reqstr = request.GetRequestStream();
reqstr.Write(buffer, 0, buffer.Length);
reqstr.Close();
response = (HttpWebResponse)request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream);
responseString = reader.ReadToEnd();
}
}
catch (Exception)
{
throw;
}
but I keep getting the error
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
what is problem? thank you
Try this Added this line:-
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Use SecurityProtocolType.Ssl3 if needed for compatibility reasons
Refer More From Here which help you alot
I have a p12 certificate, that I load it in this way:
X509Certificate2 certificate = new X509Certificate2(certName, password,
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);
It is loaded correcty, in fact If i do certificate.PrivateKey.ToXmlString(true); it returns a complete xml without errors.
But If I do:
try
{
X509Chain chain = new X509Chain();
var chainBuilt = chain.Build(certificate);
Console.WriteLine("Chain building status: "+ chainBuilt);
if (chainBuilt == false)
foreach (X509ChainStatus chainStatus in chain.ChainStatus)
Console.WriteLine("Chain error: "+ chainStatus.Status);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
it writes:
Chain building status: False
Chain error: RevocationStatusUnknown
Chain error: OfflineRevocation
so when I do:
ServicePointManager.CheckCertificateRevocationList = false;
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
ServicePointManager.Expect100Continue = true;
Console.WriteLine("connessione a:" + host);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(host);
req.PreAuthenticate = true;
req.AllowAutoRedirect = true;
req.ClientCertificates.Add(certificate);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
string postData = "login-form-type=cert";
byte[] postBytes = Encoding.UTF8.GetBytes(postData);
req.ContentLength = postBytes.Length;
Stream postStream = req.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
WebResponse resp = req.GetResponse();
the server says that the certificate is not sent/valid.
My question is:
how can I sent the certificate even with chain build false?
there is another class to post a certificate that does not check the certificate validation before send it?
many thanks.
Antonino
I resolved the problem, The point is that a P12 file (as a PFX) contains more then 1 certificate, so it must be loaded in this way:
X509Certificate2Collection certificates = new X509Certificate2Collection();
certificates.Import(certName, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
and added to a HttpWebRequest in this way: request.ClientCertificates = certificates;
Thanks everybody for support.
COMPLETE SAMPLE CODE
string host = #"https://localhost/";
string certName = #"C:\temp\cert.pfx";
string password = #"password";
try
{
X509Certificate2Collection certificates = new X509Certificate2Collection();
certificates.Import(certName, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(host);
req.AllowAutoRedirect = true;
req.ClientCertificates = certificates;
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
string postData = "login-form-type=cert";
byte[] postBytes = Encoding.UTF8.GetBytes(postData);
req.ContentLength = postBytes.Length;
Stream postStream = req.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
string line = reader.ReadLine();
while (line != null)
{
Console.WriteLine(line);
line = reader.ReadLine();
}
}
stream.Close();
}
catch(Exception e)
{
Console.WriteLine(e);
}
The problem is that you install private key to machine store which is not generally allowed to use for client authentication for processes that doesn't run under local system account or have explicit private key permissions. You need to install the key in the current user store:
X509Certificate2 certificate = new X509Certificate2(certName, password,
X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable);
I created a command-line program using a modified version of your code with a pfx cert containing the private key exported from IE and I'm able to authenticate to a secure website and retrieve protected pages:
string host = #"https://localhost/";
string certName = #"C:\temp\cert.pfx";
string password = #"password";
try
{
X509Certificate2 certificate = new X509Certificate2(certName, password);
ServicePointManager.CheckCertificateRevocationList = false;
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;
ServicePointManager.Expect100Continue = true;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(host);
req.PreAuthenticate = true;
req.AllowAutoRedirect = true;
req.ClientCertificates.Add(certificate);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
string postData = "login-form-type=cert";
byte[] postBytes = Encoding.UTF8.GetBytes(postData);
req.ContentLength = postBytes.Length;
Stream postStream = req.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
string line = reader.ReadLine();
while (line != null)
{
Console.WriteLine(line);
line = reader.ReadLine();
}
}
stream.Close();
}
catch(Exception e)
{
Console.WriteLine(e);
}
I was trying to use a self-signed certificate whose only purpose was "Server certificate" as a client certificate using the following code:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://serverurl.com/test/certauth");
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
var certificate = store.Certificates.Find(X509FindType.FindByThumbprint, "a909502dd82ae41433e6f83886b00d4277a32a7b", true)[0];
request.ClientCertificates.Add(certificate);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
What I learned was that .NET Framework will accept such a certificate as a client certificate, but .NET Core will not (see https://github.com/dotnet/runtime/issues/26531).
There are two solutions:
Switch to .NET Framework
Generate a new self-signed certificate that has a purpose / Enhanced Key Usage = Client certificate. Then the code will work in Core as well.
I'm trying to connect to a web service using C# and digest authentication, but every time I got the 401 - Not Authorized error. But when I try to reach the service over Firefox, everything's OK. When I use IE8, my password is not accepted and I got a 401.
Do you have any ideas? Thanks for the help.
Here's the test code I'm using:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback
= delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
Uri uri = new Uri(URL);
NetworkCredential netCredential = new NetworkCredential(username, password);
CredentialCache cache = new CredentialCache();
cache.Add(URL, 443, "Digest", netCredential);
WebRequest request = WebRequest.Create(URL);
request.Credentials = cache;
request.PreAuthenticate = true;
request.Method = "POST";
WebResponse response;
try
{
response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string result = reader.ReadToEnd();
Response.Write(result);
response.Close();
reader.Close();
}
catch (Exception ex)
{
Response.Write("Error: " + ex.Message + "<br/><br/><br/>");
Response.Write("Request Headers<br/><br/>");
WebHeaderCollection headers = request.Headers;
// Get each header and display each value.
foreach (string key in headers.AllKeys)
{
string value = headers[key];
Response.Write(key + ": " + value);
Response.Write("<br/><br/>");
}
}
You are using the wrong overload of CredentialCache.Add, you should use CredentialCache.Add(Uri, string, NetworkCredential) instead. The first one (with the port number) is only for SMTP.
cache.Add(uri, "Digest", netCredential);