Consume WSDL file using .net - c#

I am trying to consume a WSDL file from a third party in .net web API but it's retrieving.
Third-party sent me a Certificate that needs to be installed on the machine that wants to send a request and I already installed it.
In SoapUI it succeeded, with these configurations:
I can't mimic the configuration in SoupUI in .net.
This is what I have done:
var binding = GetBinding();
var endpointAddress = GetEndpointAddress("Endpoint URL");
if (endpointAddress != null)
{
ChannelFactory<IVitalEventsChannel> factory = null;
IVitalEventsChannel serviceProxy = null;
try
{
factory = new ChannelFactory<IVitalEventsChannel>(binding, endpointAddress);
factory.Credentials.UserName.UserName = "Username";
factory.Credentials.UserName.Password = "Passowrd";
serviceProxy = factory.CreateChannel();
gePersonalRequest gePersonalReq = new gePersonalRequest("National number");
serviceProxy.Open();
var remoteAddress = serviceProxy.RemoteAddress;
var state = serviceProxy.State;
var result = await serviceProxy.gePersonalAsync(gePersonalReq);
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (Exception ex)
{
//await client.CloseAsync();
factory.Close();
((ICommunicationObject)serviceProxy).Close();
return BadRequest(new { error = ex.Message });
}
}
Binding part looks like this:
private BasicHttpsBinding GetBinding()
{
var httpsBinding = new BasicHttpsBinding(BasicHttpsSecurityMode.TransportWithMessageCredential);
httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
//var httpsBinding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);
WSHttpBinding b = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
b.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
httpsBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Basic;
httpsBinding.Security.Mode = BasicHttpsSecurityMode.TransportWithMessageCredential;
httpsBinding.MaxBufferSize = int.MaxValue;
httpsBinding.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
httpsBinding.MaxReceivedMessageSize = int.MaxValue;
httpsBinding.AllowCookies = true;
return httpsBinding;
}

Related

FCMSender Using AspNetCore API

i am using fcm to send push notifications from api to the clients the code which i was using it below:
if (notificationModel.IsDeviceAndroid){
FcmSettings settings = new FcmSettings(){
SenderId = _notificationSettings.SenderId,
ServerKey = _notificationSettings.ServerKey
};
string authorizationKey = string.Format("keyy={0}", settings.ServerKey);
string deviceToken = notificationModel.DeviceId;
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", authorizationKey);
httpClient.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
DataPayload dataPayload = new DataPayload();
dataPayload.Title = notificationModel.Title;
dataPayload.Body = notificationModel.Body;
GoogleNotification notification = new GoogleNotification();
notification.Data = dataPayload;
notification.Notification = dataPayload;
var fcm = new FcmSender(settings,httpClient);
try {
var fcmSendResponse = await fcm.SendAsync(deviceToken, notification);
if (fcmSendResponse.IsSuccess()) {
var resposne = new GetNotificationResponseDto(){
Title = notificationModel.Title,
Message = notificationModel.Body
};
return new ServiceResponse<GetNotificationResponseDto>(resposne);
} else {
var resposne = new GetNotificationResponseDto(){
Title = "Error",
Message = "Notification dose not sent"
};
return new ServiceResponse<GetNotificationResponseDto>(resposne);
}
}catch(ArgumentException ex){
return new ServiceResponse<GetNotificationResponseDto>(default) {
Error = new ResponseError(ex.Message)
};
}
The code is working on the local machine and send notification to the client successfully.
but i got the internal server error 500 on the remote server so please can anyone give me the solution for this error
thank you

Accessing a REST service which has a Client Certificate in Xamarin targeting Android

Does anyone know the best way to implement accessing a REST service which has a Client Certificate in Xamarin targeting Android?. I'm using .NET Standard 2.0 project for the shared code.
I've tried WebRequestHandler to add the certificate, but mono does not seem to support this and the application won't run. I have also tried HttpClientHandler.
Code snippet below :
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
X509Certificate2 certificate = App.CertificateFile;
var handler = new WebRequestHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual
};
handler.ClientCertificates.Add(certificate);
var client = new HttpClient(handler);
There is a similar question posted here Using custom SSL client certificates System.Net.HttpClient on Mono
but was a while ago so hoping things have improved. My code works correctly from a .Standard 2.0 project if called via a console app, but the same code does not work on the device.
You can try AndroidClientHandler and Programatically using androidClientHandler:
AndroidClientHandler clientHandler = new AndroidClientHandler();
Java.Security.Cert.X509Certificate cert = null;
try
{
CertificateFactory factory = CertificateFactory.GetInstance("X.509");
using (var stream = Application.Context.Assets.Open("MyCert.pfx"))
{
cert = (Java.Security.Cert.X509Certificate)factory.GenerateCertificate(stream);
}
} catch (Exception e)
{
System.Console.WriteLine(e.Message);
}
if (clientHandler.TrustedCerts != null)
{
clientHandler.TrustedCerts.Add(cert);
}
else
{
clientHandler.TrustedCerts = new List<Certificate>();
clientHandler.TrustedCerts.Add(cert);
}
HttpClient client = new HttpClient(clientHandler);
Update:
If the up codes doesn't work, you can try the Android Native implementation, which leverage the same thing as AndroidClientHandler, but are more flexible for use:
var keyStore = KeyStore.GetInstance("PKCS12");
string clientCertPassword = "password_of_certificate";
using (var stream = Application.Context.Assets.Open("cert.pfx"))
{
keyStore.Load(stream, clientCertPassword.ToCharArray());
}
KeyManagerFactory kmf = KeyManagerFactory.GetInstance("x509");
kmf.Init(keyStore, clientCertPassword.ToCharArray());
IKeyManager[] keyManagers = kmf.GetKeyManagers();
SSLContext sslContext = SSLContext.GetInstance("TLS");
sslContext.Init(keyManagers, null, null);
String result = null;
HttpURLConnection urlConnection = null;
HttpStatus lastResponseCode;
try
{
URL requestedUrl = new URL("https://10.106.92.42:444");
urlConnection = (HttpURLConnection)requestedUrl.OpenConnection();
if (urlConnection is HttpsURLConnection) {
((HttpsURLConnection)urlConnection).SSLSocketFactory = sslContext.SocketFactory;
}
urlConnection.RequestMethod = "GET";
urlConnection.ConnectTimeout = 1500;
urlConnection.ReadTimeout = 1500;
lastResponseCode = urlConnection.ResponseCode;
result = ReadFully(urlConnection.InputStream);
string lastContentType = urlConnection.ContentType;
}
catch (Exception ex)
{
result = ex.ToString();
}
finally
{
if (urlConnection != null)
{
urlConnection.Disconnect();
}
}

Is this why a WCF SSL Secure Channel is faulting?

I'm supporting a project where we recently needed to apply a series of upgrades to a newer version of the .Net Framework. This has largely succeeded but for one final component that's been around for a very long time.
Our client uses InfoPath templates to populate information for other users to consume. Everything the templates need comes from a WCF web service we host. We set the web service call up with the following code.
private WSHttpBinding CreateBinding()
{
var wsHttpBinding = new WSHttpBinding();
wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.BypassProxyOnLocal = false;
wsHttpBinding.TransactionFlow = false;
wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
wsHttpBinding.MaxBufferPoolSize = 524288;
wsHttpBinding.MaxReceivedMessageSize = 2147483647;
wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
wsHttpBinding.TextEncoding = Encoding.UTF8;
wsHttpBinding.UseDefaultWebProxy = true;
wsHttpBinding.AllowCookies = false;
wsHttpBinding.ReaderQuotas.MaxDepth = 32;
wsHttpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384;
wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096;
wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;
wsHttpBinding.ReliableSession.Ordered = true;
wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.ReliableSession.Enabled = false;
wsHttpBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
wsHttpBinding.Security.Transport.Realm = string.Empty;
wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
wsHttpBinding.Security.Message.NegotiateServiceCredential = false;
wsHttpBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Basic256;
return wsHttpBinding;
}
private EndpointAddress CreateEndPoint()
{
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 certificate = store.Certificates.Find(X509FindType.FindBySubjectName, "*.wildcard.address.foo", false)[0];
store.Close();
EndpointIdentity identity = EndpointIdentity.CreateX509CertificateIdentity(certificate);
string address = getWcfServiceUrl();
AddressHeader header = AddressHeader.CreateAddressHeader(address);
List<AddressHeader> headerList = new List<AddressHeader> { header };
Uri uri = new Uri(address);
var endpointAddress = new EndpointAddress(uri, identity, headerList.ToArray());
return endpointAddress;
}
}
This works fine and if we're testing it out, calls can be made successfully for all other intents and purposes. Except for one.
In one case we need to get information from a 3rd party resource. In that situation, our web service makes a separate call out to this 3rd party at an HTTPS address (passed in to the url parameter here:
private string requestURL(string url)
{
string toReturn = null;
Stream stream = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = httpMethod;
stream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
StreamReader reader = new StreamReader(stream);
toReturn = reader.ReadToEnd();
}
catch(Exception e)
{
throw new Exception("Error with that service please try again: " + e.Message, e);
}
finally
{
if(stream != null)
{
stream.Close();
}
}
return toReturn;
}
In this case, the following error is returned:
The request was aborted: Could not create SSL/TLS secure channel.
My suspicion is that we're setting up a very specific set of constraints around the SSL connection between our local client (i.e. InfoPath) and the web service but the call from that web service to the 3rd party is not set up with any constraints beyond simply calling over HTTPS.
What should I be looking out for in trying to fix this issue?
WCF IMHO is particular about configuration at both ends and asks for things like transport credential specifically in the back and forth. I suspect you have no control of how the security is managed at the third party and can't change it, but your generic method to call all web services won't work because the configuration doesn't match.

active client - get token from resource partner adfs using idp token

I am trying to write console application with the following scenario:
client first requests a token from an identity provider, and then uses this token to request a new token from a Resource STS
Using the following link: http://leastprivilege.com/2010/10/28/wif-adfs-2-and-wcfpart-6-chaining-multiple-token-services/
I managed get the token from Idp but didn't managed getting the token from Resource STS.
This is my code:
string RPRealm = "https://service.contoso.com/";
string RSTSRealm = "http://fsweb.contoso.com/adfs/services/trust";
string IdPstsEndpoint = "https://IdpAdfs.domain.com/adfs/services/trust/13/kerberosmixed";
string RSTSEndpoint = "https://fsweb.contoso.com/adfs/services/trust/13/IssuedTokenMixedSymmetricBasic256";
private static SecurityToken GetIdPToken(string rstsRealm, string IdPstsEndpoint)
{
using (var factory = new WSTrustChannelFactory(
new KerberosWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(new Uri(IdPstsEndpoint))))
{
WSTrustChannel channel = null;
factory.TrustVersion = TrustVersion.WSTrust13;
try
{
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress(rstsRealm),
KeyType = WSTrust13Constants.KeyTypes.Bearer,
};
channel = (WSTrustChannel)factory.CreateChannel();
RequestSecurityTokenResponse rstr;
SecurityToken token = channel.Issue(rst, out rstr);
return token;
}
finally
{
if (channel != null)
{
channel.Abort();
}
factory.Abort();
}
}
}
private static SecurityToken GetRSTSToken(SecurityToken IdPToken, string RSTSEndpoint, string RPRealm)
{
var binding = new WS2007FederationHttpBinding();
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Mode = WSFederationHttpSecurityMode.TransportWithMessageCredential;
using (var factory = new WSTrustChannelFactory(
binding,
new EndpointAddress(new Uri(RSTSEndpoint))))
{
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress(RPRealm),
KeyType = WSTrust13Constants.KeyTypes.Bearer,
};
factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
factory.TrustVersion = TrustVersion.WSTrust13;
factory.Credentials.SupportInteractive = false;
factory.ConfigureChannelFactory();
var channel = factory.CreateChannelWithIssuedToken(IdPToken);
RequestSecurityTokenResponse rstr;
SecurityToken token = channel.Issue(rst, out rstr);
return token;
}
}
I get this error:
The content type text/html of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8)
what is worng with my code?
Thanks in advance
ADFS does not support bearer tokens on its federation endoints. In other words, on your first hop you need to specify a KeyTypes.Symmetric on the RST.

Create a WCF REST Client Proxy Programatically (in C#)

I am trying to create a REST Client proxy programatically in C# using the code below but I keep getting a CommunicationException error. Am I missing something?
public static class WebProxyFactory
{
public static T Create<T>(string url) where T : class
{
ServicePointManager.Expect100Continue = false;
WebHttpBinding binding = new WebHttpBinding();
binding.MaxReceivedMessageSize = 1000000;
WebChannelFactory<T> factory =
new WebChannelFactory<T>(binding, new Uri(url));
T proxy = factory.CreateChannel();
return proxy;
}
public static T Create<T>(string url, string userName, string password)
where T : class
{
ServicePointManager.Expect100Continue = false;
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode =
WebHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
binding.UseDefaultWebProxy = false;
binding.MaxReceivedMessageSize = 1000000;
WebChannelFactory<T> factory =
new WebChannelFactory<T>(binding, new Uri(url));
ClientCredentials credentials = factory.Credentials;
credentials.UserName.UserName = userName;
credentials.UserName.Password = password;
T proxy = factory.CreateChannel();
return proxy;
}
}
So that I can use it as follows:
IMyRestService proxy = WebProxyFactory.Create<IMyRestService>(url, usr, pwd);
var result = proxy.GetSomthing(); // Fails right here
For this to work with Forms Authentication, I had to physically override the Authentication headers as follows:
var proxy = WebProxyFactory.Create<ITitleWorldService>(url, userName, password);
using (new OperationContextScope((IContextChannel)proxy))
{
var authorizationToken = GetBasicAuthorizationToken(userName, password);
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = authorizationToken;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
//var response = proxy.DoWork();
Console.WriteLine(proxy.SayHello());
}

Categories