DISCLAIMER: I know that this question was asked before multiple times, non of the answers helped me.
In our app, we implemented SSL for more security, but we sometimes get the mentioned error, the error is not persistent, meaning that the same route can success at time but other time it throws this error.
Nothing is displayed on the server logs.
This is how I setup SSL configuration in the app:
(client.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (HttpClient _client) {
SecurityContext sc = SecurityContext();
sc.setTrustedCertificatesBytes(sslCert.buffer.asInt8List());
HttpClient httpClient = HttpClient(context: sc);
httpClient.badCertificateCallback = (X509Certificate cert, String host, int port) => false;
httpClient.maxConnectionsPerHost = 10;
return httpClient;
};
client being a Dio instance
Our server is built using Node.js, with Apache on centOS
Related
In my .NET Framework 4.6.1 application I am using StackExchange.Redis.StrongName 1.2.6 to connect to Azure Redis.
This is the code
public RedisContext(string connectionString = null)
{
if (connectionString == null) return;
Lazy<ConfigurationOptions> lazyConfiguration
= new Lazy<ConfigurationOptions>(() => ConfigurationOptions.Parse(connectionString));
var configuration = lazyConfiguration.Value;
configuration.SslProtocols = SslProtocols.Tls12;//just added
configuration.AbortOnConnectFail = false;
Lazy<ConnectionMultiplexer> lazyConnection =
new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(configuration));
_connectionMultiplexer = lazyConnection.Value;
LogProvider.IsDisabled = true;
var connectionEndpoints = _connectionMultiplexer.GetEndPoints();
_lockFactory = new RedisLockFactory(connectionEndpoints.Select(endpoint => new RedisLockEndPoint
{
EndPoint = endpoint,
Password = configuration.Password,
Ssl = configuration.Ssl
}));
}
In Azure, I have changed the Redis resource to use TLS1.2 and in code I have added this line:
configuration.SslProtocols = SslProtocols.Tls12;//just added
And now, nothing works anymore. This is the error I get in Application Insights:
Error connecting to Redis. It was not possible to connect to the redis server(s); ConnectTimeout
I have also tried to add ",ssl=True,sslprotocols=tls12" to the redis connection string, but with the same result.
Try referencing StackExchange.Redis instead of StackExchange.Redis.StrongName. I have done that in a few of my projects and now it works. However some 3rd party still use StrongName rather than the normal redis one. StackExchange.Redis.StrongName is now deprecated. https://github.com/Azure/aspnet-redis-providers/issues/107. I assume you are trying to connect to Azure Redis in relation to them stopping TLS 1.0 and 1.1 support?
I have been stuck in one issue. I am getting error of "Unable to connect to the remote server. An attempt was made to access a socket in a way forbidden by its access permissions".
After searching on web and taking help of azure support, I came to know that if Web App reaches outbound connection limit of azure web app instance, it refuses connections or kill extra connections. Here is the image of open socket handles
My application calls third party WebAPI and wcf service. I have written code to close connections after making call to APIs. but it doesn't work for me. I did following code to call Web API.
var request = (HttpWebRequest)WebRequest.Create("www.xyz.com");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = false;
request.Headers.Add("Authorization", "Handshake");
byte[] bodyData;
bodyData = Encoding.UTF8.GetBytes(input_data);
request.ContentLength = bodyData.Length;
request.GetRequestStream().Write(bodyData, 0, bodyData.Length);
request.GetRequestStream().Flush();
request.GetRequestStream().Close();
using (var response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream(),
Encoding.UTF8))
{
string output_data = reader.ReadToEnd();
}
response.Close();
}
Could anyone guide me how to get rid on this issue?
Im not sure if this should just go direct to the github but I thought id check here first if anyone has encountered this issue before.
I recently have upgraded one of my apps to use dot net 2.0.3 From 1.1.4.
Everything works fine locally but when I deploy to my app service in azure I get the following exception.
System.Text.DecoderFallbackException: Unable to translate bytes [8B] at index 1 from specified code page to Unicode.
The code that calls it is a httpclient that talks between the apps.
public async Task<T1> Get<T1>(string url, Dictionary<string, string> urlParameters = null) where T1 : DefaultResponse, new()
{
var authToken = _contextAccessor.HttpContext.Request.Cookies["authToken"];
using (var client = new HttpClient().AcceptJson().Acceptgzip().AddAuthToken(authToken))
{
var apiResponse = await client.GetAsync(CreateRequest(url, urlParameters));
T1 output;
if (apiResponse.IsSuccessStatusCode)
{
output = await apiResponse.Content.ReadAsAsync<T1>();
//output.Succeeded = true;
}
else
{
output = new T1();
var errorData = GlobalNonSuccessResponseHandler.Handle(apiResponse);
output.Succeeded = false;
output.Messages.Add(errorData);
}
return output;
}
}
public static HttpClient AcceptJson(this HttpClient client)
{
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
public static HttpClient Acceptgzip(this HttpClient client)
{
// Commenting this out fixes the issue.
//client.DefaultRequestHeaders.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("deflate"));
return client;
}
public static HttpClient AddAuthToken(this HttpClient client, string authToken)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
return client;
}
Im a bit stumped as to whats going on.
So I have 2 apps which we call client and server from now on.
Client uses the above code to talk to the server.
Locally this is fine on azure not so, this all worked fine before upgrading.
So I setup the client locally to talk to the server on azure I was able to replicate the issue.
I had a look at the response in fiddler and it is able to correctly decode it.
If anyone has any idea where I should look and has seen it before any info would be great :D.
UPDATE 1
So after some more digging I decided to remove gzip and then everything started working.
client.DefaultRequestHeaders.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("gzip"));
Can anyone explain this?
8B can be a second byte of multi-byte UTF8 character. The DecoderFallbackException tells that you’re interpreting the data as some other encoding. Probably Latin-1 which doesn’t have 8B character.
In fiddler, you should look at the content-type HTTP header in the response. If it says application/json or application/json; charset=utf-8, it’s probably a bug in .NET, because even without charset=utf-8 RFC 4627 says the default encoding is already UTF-8.
If it says something else, I would try changing the server so it sends the correct content-type header in the response.
Following is my code for the secure ssl server. I have created a keystore "server" and it has the key pair generated with passwords.
public static void main(String[] args) throws Exception {
Server server = new Server();
HttpConfiguration https_config = new HttpConfiguration();
https_config.setSecureScheme("https");
https_config.setSecurePort(8443);
https_config.addCustomizer(new SecureRequestCustomizer());
https_config.setSendServerVersion(true);
File keystoreFile = new File("server");
System.out.print(keystoreFile.getAbsolutePath());
SslContextFactory sslContextFactory = new SslContextFactory();
if (keystoreFile.exists())
{
sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
sslContextFactory.setTrustStorePath(keystoreFile.getAbsolutePath());
sslContextFactory.setKeyStorePassword("secret");
sslContextFactory.setKeyManagerPassword("secret");
sslContextFactory.setTrustStorePassword("secret");
sslContextFactory.setExcludeCipherSuites(
"SSL_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
}
ServerConnector https =
new ServerConnector(server,
new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config));
https.setPort(8443);
server.setConnectors(new Connector[] { https});
ServletContextHandler scHandler = new ServletContextHandler(server,"/");
scHandler.addServlet(Testpage1.class, "/test");
server.setHandler(scHandler);
server.start();
}
}
when I tried to connect to using the https://localhost:8443/ or https://localhost:8443/test it gives me "web page not available error" and with curl it gives me "curl: (35) Unknown SSL protocol error in connection to localhost:8443"
Could some one guide me to debug this issue.
I decided to post the question after a full day of debugging and trials and but with a little suggestion from a friend I manage to solve the issue by updating the keystore. So the issue I was having was due to the keys I have generated int he key store. It seems you need to use RSA algorithm not the EC algorithm.
Sorry for the long title, but it seems to be the best summary based on what I know so far.
We’re currently working on a Universal App that needs to access some documents on a Sharepoint server via the REST API using NTLM Authentication, which proves to be more difficult than it should be. While we were able to find workarounds for all problems (see below), I don’t really understand what is happening and why they are even necessary.
Somehow the HttpClient class seems to behave differently on the phone and on the PC. Here’s what I figured out so far.
I started with this code:
var credentials = new NetworkCredential(userName, password);
var handler = new HttpClientHandler()
{
Credentials = credentials
};
var client = new HttpClient(handler);
var response = await client.GetAsync(url);
This works fine in the Windows app, but it fails in the Windows Phone app. The server just returns a 401 Unauthorized status code.
Some research revealed that you need to provide a domain to the NetworkCredential class.
var credentials = new NetworkCredential(userName, password, domain);
This works on both platforms. But why is the domain not required on Windows?
The next problem appears when you try to do multiple requests:
var response1 = await client.GetAsync(url);
var response2 = await client.GetAsync(url);
Again, this works just fine in the Windows app. Both requests return successfully:
And again, it fails on the phone. The first request returns without problems:
Strangely any consecutive requests to the same resource fail, again with status code 401.
This problem has been encountered before, but there doesn’t seem to be a solution yet.
An answer in the second thread suggests that there’s something wrong with the NTLM handshake. But why only the second time?
Also, it seems to be a problem of the HttpClient class, because the following code works without problems on both platforms:
var request3 = WebRequest.CreateHttp(url);
request3.Credentials = credentials;
var response3 = await request3.GetResponseAsync();
var request4 = WebRequest.CreateHttp(url);
request4.Credentials = credentials;
var response4 = await request4.GetResponseAsync();
So the problem only appears:
on Windows Phone. The same code in a Windows App works.
when connecting to Sharepoint. Accessing another site with NTLM authentication works on both platforms.
when using HttpClient. Using WebRequest, it works.
So while I'm glad that I at least found some way to make it work, I’d really like to know what’s so special about this combination and what could be done to make it work?
Hi Daniel at the same problem when I do my sync, because windows phone had a lot of problems with cache, finallt I could solve with add headers.
Also I think so it's good idea that you use the timeout because it's a loooong response you can wait a lot of time... And the other good way to work it's use "using", it's similar that use ".Dispose()". Now I show you the code:
var request3 = WebRequest.CreateHttp(url);
request3.Credentials = credentials;
request.ContinueTimeout = 4000; //4 seconds
//For solve cache problems
request.Headers["Cache-Control"] = "no-cache";
request.Headers["Pragma"] = "no-cache";
using(httpWebResponse response3 = (httpWebResponse) await request3.GetResponseAsync()){
if (response3.StatusCode == HttpStatusCode.OK)
{
//Your code...
}
}
var request4 = WebRequest.CreateHttp(url);
request4.Credentials = credentials;
request.ContinueTimeout = 4000; //4 seconds
//For solve cache problems
request.Headers["Cache-Control"] = "no-cache";
request.Headers["Pragma"] = "no-cache";
using(httpWebResponse response4 = (httpWebResponse) await request4.GetResponseAsync()){
if (response4.StatusCode == HttpStatusCode.OK)
{
//Your code...
}
}
I wait that my code can help you. Thanks and good luck!