C#: I want to create a simple SOAP client - c#

I need to have a Client authentication via a certificate or better a keystorefile (myfile.p12).
I used it in SoapUI and there it worked. I got the Infos about the available requests.
If I try to add a Service reference to my empty Project, it always fails.
There was an error downloading 'https://MYURL/api?wsdl/$metadata'.The request was aborted: Could not create SSL/TLS secure channel. Metadata contains a reference that cannot be resolved: 'https://MYURL/soapWebService/api?wsdl'. Could not establish secure channel for SSL/TLS with authority 'myurl:8443'. The request was aborted: Could not create SSL/TLS secure channel.

I used the following code
var privCert = new X509Certificate2(#"c:\temp\test.p12", "testpass");
// privCert.Verify() => FALSE! WHY???
if (privCert.Verify()) Console.WriteLine("true");
else Console.WriteLine("false");
// create Web Request and set CLient Certificate für the authentication
HttpWebRequest request = CreateWebRequest();
request.ClientCertificates.Add(privCert);
// Create SOAP Message for PING Command
XmlDocument soapEnvelopeXml = new XmlDocument();
soapEnvelopeXml.LoadXml(#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:ws=""http://ws.soap.transfer.services.sedna.ser.com/"">
<soap:Header/>
<soap:Body>
<ws:ping>
<sessionUUID>something</sessionUUID>
</ws:ping>
</soap:Body>
</soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
Console.WriteLine("Credentials of request = " + request);
// Send Command to Webservice
try
{
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("\nTaste!");
Console.ReadKey();
}
static HttpWebRequest CreateWebRequest()
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(#"https://doxapd01.zit.commerzbank.com:8443/soapWebService");
webRequest.Headers.Add(#"SOAP:Action");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}

Related

HttpWebRequest get unauthorized exception

Trying to call a remote server using the following code I get always the unauthorized exception from the server:
HttpWebRequest webRequest;
var myURI = "https://myURI";
webRequest = (HttpWebRequest)WebRequest.Create(myURI);
webRequest.Method = "GET";
string myCredentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("myUsername" + ":" + "myPassword"));
webRequest.Headers.Add("Authorization", "Basic " + myCredentials);
HttpWebResponse webResponse;
webResponse = (HttpWebResponse)webRequest.GetResponse();
string response = string.Empty;
using (StreamReader sr = new StreamReader(webResponse.GetResponseStream()))
{
response = sr.ReadToEnd();
sr.Close();
}
System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'
WWW-Authenticate: Basic realm="geoserver"
Cache-Control: proxy-revalidate
Connection: Keep-Alive
Set-Cookie: BCSI-CS-**********=1; Path=/
Proxy-Support: Session-based-authentication
Content-Type: text/plain; charset=UTF-8
Content-Length: 23
It is a litte bit weird because, if I try (almost) the same thing via postman, it works and i get the correct response from the remote server (without 401).
I've also tried other ways like the follwing code, but nothing helps:
CredentialCache cc = new CredentialCache();
cc.Add(
new Uri("https://mywebserver/webpage"),
"Basic", //also tried NTLM
new NetworkCredential("user", "password"));
webRequest.Credentials = cc;
If I try to call an other server with the same code it works.
As you can see in the Exception, has a Session-based-authentication. The problem is: There is no documentation for the reverse proxy and I cannot find an endpoint in order to get a clean cookie. As workaround i've tried the fllowing code and it works now.
It's maybe not the best way to set the Cookie as HttpHeader.
static void Main(string[] args)
{
HttpWebRequest webRequest = CreateWebRequest();
string cookie = null;
HttpWebResponse webResponse;
try
{
webResponse = (HttpWebResponse) webRequest.GetResponse();
}
catch (WebException ex)
{
var headers = (WebHeaderCollection)ex.Response.GetType().GetProperty("Headers").GetValue(ex.Response, null);
cookie = headers.Get("Set-Cookie");
webRequest = CreateWebRequest();
webRequest.Headers.Add("Cookie", cookie);
webResponse = (HttpWebResponse) webRequest.GetResponse();
}
string response = string.Empty;
using (StreamReader sr = new StreamReader(webResponse.GetResponseStream()))
{
response = sr.ReadToEnd();
sr.Close();
}
}
private static HttpWebRequest CreateWebRequest()
{
HttpWebRequest webRequest;
var myURI = "https://myURI";
webRequest = (HttpWebRequest)WebRequest.Create(myURI);
webRequest.Method = "GET";
string myCredentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("myUsername" + ":" + "myPassword"));
webRequest.Headers.Add("Authorization", "Basic " + myCredentials);
return webRequest;
}

sending Tr064 Requests to AVM FritzBox 7270

I am just learning how to send SOAP requests to my AVM FritzBox 7270 router using C#.
Here ist my method that sends a SOAP request to the router:
private string Execute(string controlUrl, string serviceType, string action)
{
WebRequest webRequest = WebRequest.Create("http://fritz.box:49000" + controlUrl);
HttpWebRequest httpRequest = (HttpWebRequest)webRequest;
httpRequest.Method = "POST";
httpRequest.ContentType = "text/xml; charset=utf-8";
httpRequest.Headers.Add("SOAPACTION", string.Format("{0}#{1}", serviceType, action));
httpRequest.ProtocolVersion = HttpVersion.Version11;
httpRequest.Credentials = new NetworkCredential("username", "password");
Stream requestStream = httpRequest.GetRequestStream();
StreamWriter streamWriter = new StreamWriter(requestStream, Encoding.ASCII);
streamWriter.Write(GetBody(serviceType, action));
streamWriter.Close();
//Get the Response
try
{
HttpWebResponse wr = (HttpWebResponse)httpRequest.GetResponse();
StreamReader srd = new StreamReader(wr.GetResponseStream());
return srd.ReadToEnd();
}
catch (WebException)
{
return null;
}
}
Function GetBody:
private string GetBody(string serviceType, string action)
{
const string fmt = #"<?xml version=""1.0"" encoding=""utf-8""?>
<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"" s:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/"">
<s:Body>
<u:{0} xmlns:u=""{1}"" />
</s:Body>
</s:Envelope>
";
return string.Format(fmt, action, serviceType);
}
}
I tested this method with parameters that I found anywhere in the internet:
controlUrl = "/upnp/control/WANIPConn1"
serviceType = "urn:schemas-upnp-org:service:WANIPConnection:1"
action = "GetExternalIPAddress"
This works well.
However, I think I should go the official way and first send a request
http://fritz.box:49000/tr64desc.xml
to receive parameters valid for my actual router. In the response to this request I find the following node:
<service>
<serviceType>urn:dslforum-org:service:WANIPConnection:1</serviceType>
<serviceId>urn:WANIPConnection-com:serviceId:WANIPConnection1</serviceId>
<controlURL>/upnp/control/wanipconnection1</controlURL>
<eventSubURL>/upnp/control/wanipconnection1</eventSubURL>
<SCPDURL>/wanipconnSCPD.xml</SCPDURL>
</service>
Using these values for serviceId and controlUrl, I get error 500 (Internal Server Error).
Who can help me? What is wrong in my code?
I think the problem is solved:
There seem to be a lot of undocumeted features of the Fritz.Box, and the pararmeters I found in the internet oviously are part of thease features.
With
<service>
<serviceType>urn:dslforum-org:service:WANPPPConnection:1</serviceType>
<serviceId>urn:WANPPPConnection-com:serviceId:WANPPPConnection1</serviceId>
<controlURL>/upnp/control/wanpppconn1</controlURL>
<eventSubURL>/upnp/control/wanpppconn1</eventSubURL>
<SCPDURL>/wanpppconnSCPD.xml</SCPDURL>
</service>
I can call
GetExternalIPAddress
without problems.

Error Paypal sandbox: The request was aborted: Could not create SSL/TLS secure channel

I am getting error "The request was aborted: Could not create SSL/TLS secure channel." in case of sandbox however this works with my live credentials.
here is the code snippet
var uri = new Uri(url);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var request = WebRequest.Create(uri);
var encoding = new UTF8Encoding();
var requestData = encoding.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Timeout = (300 * 1000); //TODO: Move timeout to config
request.ContentLength = requestData.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(requestData, 0, requestData.Length);
}
var response = request.GetResponse();
string result;
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
{
result = reader.ReadToEnd();
}
return result;
The problem is C# defaults to SSL3 when trying to connect to the PayPal server, which PayPal doesn't accept. PayPal requires the (more secure) TLS 1.2 as a minimum.
You set this through the following code:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Integration of Rightmove Real Time Data Feed (RTDF) asp.net

i am integrating rightmove real time data feed (rtdf) in my property site for listing my properties on rightmove website. i am using asp.net web api to post data on rightmove listing.
they have provide me with these SSL Files [.p12,.pem,.jks]. i have imported .p12 certificate in my local machine personal store and sending it in my http request
to rightmove test api link provide by rightmove.
i am getting the following error from server.
The remote server returned an error: 403 forbidden.
i checked my certificate loaded successfully in the request, below is my code
public static string PostData(string data, string url)
{
String result = "";
try
{
byte[] bytebuffer = Encoding.UTF8.GetBytes(data);
HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
objRequest.Method = "POST";
objRequest.ContentLength = bytebuffer.Length;
objRequest.ContentType = "application/json";
objRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0";
objRequest.PreAuthenticate = true;
objRequest.Accept = "application/json";
objRequest.ClientCertificates.Add(CertificateHelper.GetRightmoveApiX509Certificate());
using (Stream stream = objRequest.GetRequestStream())
{
stream.Write(bytebuffer, 0, bytebuffer.Length);
stream.Close();
}
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(objResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
// Close and clean up the StreamReader
streamReader.Close();
}
}
catch (Exception e)
{
result = "Exception: " + e.Message;
}
return result;
}
help me to get rid from 403 forbidden error.
Use the following.
I have tested it and it's working fine in my case.
// Grab Certificate
X509Certificate2 cert2 = new X509Certificate2(
AppDomain.CurrentDomain.BaseDirectory + "CertificateName.p12",
CertificatePasswordHere,
X509KeyStorageFlags.MachineKeySet);
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://adfapi.adftest.rightmove.com/v1/property/sendpropertydetails");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.ClientCertificates.Clear();
httpWebRequest.ClientCertificates.Add(cert2);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(data);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}

Windows Live SDK Authorization

I'm working with Windows Live SDK from C# trying to invoke directly the rest service for getting my oAuth token, but instead I'm getting an 401 Error. Unauthorized.
I have my application registered as Desktop Application on https://manage.dev.live.com/ and published so I have my own Client ID and Secret Key.
From my desktop application I open an Internet Explorer Window for Live Login and get my Verification Code.
With that code, secret key and clientID I invoke AccessToken.aspx on this way:
try
{
string requestUrl = "https://consent.live.com/AccessToken.aspx";
// Request the access token.
string postData = string.Format("wrap_client_id={0}&wrap_client_secret={1}&wrap_verification_code={2}",
clientId,
secretKey,
verificationCode);
postData = HttpUtility.UrlEncode(postData);
byte[] postDataEncoded = System.Text.Encoding.UTF8.GetBytes(postData);
WebRequest req = HttpWebRequest.Create(requestUrl);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = postDataEncoded.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(postDataEncoded, 0, postDataEncoded.Length);
WebResponse res = req.GetResponse();
string responseBody = null;
using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.UTF8))
{
responseBody = sr.ReadToEnd();
}
// Process FORM POST.
NameValueCollection responseCollection = System.Web.HttpUtility.ParseQueryString(responseBody);
return responseCollection["wrap_access_token"];
}
catch (Exception ex)
{
throw ex;
}
What I'm doing wrong?
Thanks in advance for any help provided.
The remote server returned an error: (401) Unauthorized

Categories