On my ASP.net-based website I am aggregating feeds of my activities from several website.
One of those is the GitHub feed at https://github.com/lucamauri.atom: this is a valid feed correctly readable using a web browser and it properly worked on my website since a couple of weeks ago. Since then, it started generating errors
In the code I first create and XMLReader and then I load it in a SyndicationFeed object as follows:
Dim TempReader As System.Xml.XmlReader = System.Xml.XmlReader.Create(TempString)
Dim SyndFeed As SyndicationFeed = SyndicationFeed.Load(TempReader)
Dim TempItems As New List(Of SyndicationItem)
TempItems.AddRange(SyndFeed.Items.ToList.GetRange(0, Math.Min(CurrentFeed.TotalElements, SyndFeed.Items.Count)))
This works properly with several feeds, but the GitHub one now generate a TLS error on the first row of the above code:
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.GetResponse() at System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials, IWebProxy proxy, RequestCachePolicy cachePolicy)
at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials, IWebProxy proxy, RequestCachePolicy cachePolicy)
at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.XmlTextReaderImpl.FinishInitUriString() at System.Xml.XmlTextReaderImpl..ctor(String uriStr, XmlReaderSettings settings, XmlParserContext context, XmlResolver uriResolver)
at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputUri)
I use the same code with other HTTPS feeds (https://stackoverflow.com/feeds/user/69295 just to name one) and I do not get the error. So this is something specific to the GitHub feed, but then again I can reach it from a browser on the same machine where I run the website, so I am lost at it.
Any idea on the cause of the issue?
The server is in control of the protocol that is ultimately negotiated. The Stackoverflow server is requiring only TLS v1 as shown in the wireshark capture below. This trace was done on .Net framework version 4.
The Github feed refuses anything below TLS v1.2 and therefore fails on .Net 4.0 because that version is not available by default.
You can work around it by setting the SecurityProtocol on the ServicePointManager, if you have .Net 4.5+ installed on the same computer. If you don't, then you simply cannot make the request.
You do this by using the numeric value for the SecurityProtocol instead of the enumeration value which is not available on .Net 4.
ServicePointManager.SecurityProtocol = DirectCast(3072, SecurityProtocolType)
Having done this, you can now negotiate TLS 1.2 even on .Net 4.
However, if you can, just upgrade to a newer framework version to make it easy.
Update
There is a patch available for .Net 3.5:
https://support.microsoft.com/en-us/help/3154520/support-for-tls-system-default-versions-included-in-the-net-framework
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
.NET 4.5.1
Set this in startup class of mvc project and xmlreader worked on https links, thanks guys.
Related
I'm trying to connect to our wordpress api in our asp.net mvc application, using the following code
public static string GetLifespeakBlogListings()
{
WebClient client = new WebClient();
string url = "https://lifespeak.com/wp-json/wp/v2/posts?categories=6";
string listings = client.DownloadString(url);
return listings;
}
however I'm getting the following exception :
System.Security.SecurityException Failed to negotiate HTTPS connection with server.fiddler.network.https> HTTPS handshake to lifespeak.com (for #1) failed. System.IO.IOException Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
If I access this feed from a browser, it works fine https://lifespeak.com/wp-json/wp/v2/posts?categories=6
However, if I try from fiddler, I get the same exception:
I'm assuming that something on our wordpress site is blocking this request for some reason. Is there something I can configure to prevent this? How can I determine the cause?
The issue was that the version of System.Net I was using in my application was attempting to make the request to the wordpress API using TLS 1.0, and was getting rejected, similar to the issue with fiddler that dave pointed out above. I fixed this by adding the following line of code in the method, as specified in How to specify SSL protocol to use for WebClient class
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
Note that the value has to be added manually and cast as a SecurityProtocolType, as .net 4.0 (the version I was using) doesn't support tls1.2
I'm currently expanding the logging part of my ASP.NET Web API application but I'm having trouble identifying what encryption scheme is being used. As this logging is done through a DelegatingHandler I only have access to the HttpRequestMessage and HttpResponseMessage given to me through the middleware chain.
How do I Identify the https encryption type (SSL 3.0, TLS 1.0, TLS 1.3 etc..) used in a ASP.NET Web API DelegatingHandler?
I'm not sure if you're asking about whether the request is https or just http. If that's what you're looking for you just need httpRequestMessage.RequestUri.Scheme.
However it sounds like you're looking for more information about the certificate itself. Information about the SSL certificate isn't really a property of the individual request and can't be accessed from HttpRequestMessage or HttpResponseMessage as far as I'm aware. It's more a property of the application and machine configuration.
If you wanted to get information about the SSL certificate you could do something like this:
var store = new X509Store(StoreLocation.LocalMachine);
var certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, "thumbprint", true);
var certificate = certificateCollection[0];
var version = certificate.Version;
var signatureAlgorithm = certificate.SignatureAlgorithm;
Obviously that's just one way to do it and there's more error handling you would want to do. The general idea is you probably have access to the certificate thumbprint used by the application through the app.config. If you use that you can look up the certificate information from X509Store as I did above. Then you'll have access to all kinds of properties.
Hope that helps!
I have a .Net 4.5.2 WebApp that is calling my API. When I point my web app to the LocalHost version of my API, it gets the data, and comes back just fine. I published that API, and confirm that the API is working correctly with PostMan.
Then I run the exact same WebApp code, changing only the URI from localhost to live api, and I get a multiple exception error consisting of the following:
An existing connection was forcibly closed by the remote host
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
The underlying connection was closed: An unexpected error occurred on a send.
An error occurred while sending the request.
Here's my calling code
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("user", serializedUser);
response = null;
try
{
//Uri uri = new Uri("https://jsonplaceholder.typicode.com/posts/1");//https works
Uri uri = new Uri("https://api.acme.com/values/test");
//Uri uri = new Uri("http://localhost/5000/values/test"); //http localhost works
response = client.GetAsync(uri).Result;
}
catch (Exception e)
{
string er = e.Message;
}
}
EDIT 1: I created a .NET Core app from scratch, and my original code works perfectly calling my live API. My original code also work in .NET 4.5.2 calling a different "https" API.
EDIT 2:
So this is where I'm at now, I have created two generic apps from VS 2015, one is a .NET Core Web App, the other a .NET Framework Web App. I have used the above code exactly the same in both apps to call the API. In both apps, I can call a generic "https" api I found online (jsonplaceholder). I can also call the localhost version of my app at "http" from both. In the .NET Core version of the app, I can call my "https" live API and get the results I'm looking for. In the .NET Framework app I still get the same errors.
I can't figure out what the difference is between my Core and Framework requests that is getting one shut down when the other isn't.
It seems you are hosting the application on secured http environment (https). Are you using SSL certificate on the server where you are hosting your Web API? If not, It might be throwing the certificate related exceptions.
Just add the following line before the call to GetAsync and This will ignore the SSL errors.
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
This is only recommended in an intranet environment or other closed network where server identities can't be forged.
C# Ignore certificate errors?
Adding the following line before my API call fixed the issue, but I'd love to hear an explanation of what this line does, and any security risks this might impose using it in my web app.
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
Props to this answer!
I have an ASP.net web application and my clients need to authenticate to my website with client-side v3 certificates.
All I need to check is that:
1- the certificate is valid
2- The "Issued To CN" has a specific value
I do the following in my MVC action:
var req = Request.ClientCertificate;
req has a property called IsValid which is enough for requirement (1). Now, the issue here is that I cannot check the CN because I believe it is stored in another property of the type byte[0] called Certificate.
I tried reading the certificate like this:
var x509 = new X509Certificate(req.Certificate);
But I get two exceptions:
'x509.Issuer' threw an exception of type 'System.Security.Cryptography.CryptographicException'
'x509.Subject' threw an exception of type 'System.Security.Cryptography.CryptographicException'
How can I read the certificate?
The typical approach is to map certificate attributes (e.g. the Subject or CN) to one or more users. This is done via IIS configuration.
After that is completed, all MVC has to do is check the current user.
See also this article.
I have a Windows 8.1 Store application that I side-load on a Windows 10 Enterprise DELL tablet. The app uses data from a repository via an ASP.NET Web API installed on a remote server. The Web API is configured to use Windows Authentication. If I use Fiddler to make Web API calls I can see the several steps in the NTLM negotiation, the 401.2 HTTP Error messages returned twice before the HTTP 200 Ok.
However, my application gets the 401.1 and then it does not do anything else. In my application's package manifest, I have checked Enterprise Authentication check box in the list of required capabilities. Also, when I tested it with the Visual Studio Simulator, on my development machine, the negotiation was done and the Web API responded properly to my calls.
In order to have the NTLM Negotiation done automatically in the background, I though all that needs to be done is to have an HttpClientHandler object constructed like this:
var webApiAuthClientHandler = new HttpClientHandler()
{
Credentials = CredentialCache.DefaultNetworkCredentials,
ClientCertificateOptions = ClientCertificateOption.Automatic
};
Then, this HttpClientHandler object would be passed in the constructor of the HttpClient object used to make the Web API calls:
var webApiHttpClient = new HttpClient(webApiAuthClientHandler)
{
BaseAddress = new Uri(_myWebApiUri, UriKind.Absolute),
Timeout = new TimeSpan(0, 0, 150)
};
What am I missing? How do I get my app to automatically negotiate the authentication in the background and have my GetAsync call return the needed HTTP Code 200?
Any suggestion would be highly appreciated.
TIA,
Eddie
I see your issue has been resolved in MSDN forum: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/58620579-240d-49da-8538-cee5aff91a68/w81-sideloaded-windows-81-application-generates-an-exception-when-calling-methods-of-an-restful?forum=wpdevelop
So I post it here to help more visitors find the solution easily.
Thank you.