authentication for a Web service options - asp.net

I am new to Web services and .NET.
I have to authenticate a web service that is being accessed using http post.
I tried putting a custom soap header and sending it to the service and checking the header in service but the header object is always null in the service.
also if i put the user and password options in http headers how can i validate them on the server ?
Thanks in advance
Client code:
private void button1_Click(object sender, EventArgs e)
{
HttpWebRequest request;
string strSOAPRequestBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
"<soap:Header>"+
"<AuthHeader xmlns=\"http://tempuri.org/\">" +
"<Username>apple</Username>"+
"<Password>apple</Password>"+
"</AuthHeader>"+
"</soap:Header>"+
"<soap:Body xmlns=\"http://tempuri.org/\">"+
"<HelloWorld>"+
"</soap:Body>"+
"</soap:Envelope>";
request = (HttpWebRequest)WebRequest.Create("http://localhost:1494/Service1.asmx/HelloWorld");
request.Accept = "text/xml";
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=utf-8";
request.ContentLength = strSOAPRequestBody.Length;
using (Stream stream = request.GetRequestStream())
{
using (StreamWriter sw = new StreamWriter(stream))
{
sw.Write(strSOAPRequestBody);
sw.Flush();
}
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
{
txtResponse.Text = System.Web.HttpUtility.HtmlDecode(responseStream.ReadToEnd());
}
}
}
Service
public class Service1 : System.Web.Services.WebService
{
public AuthHeader Authentication;
[WebMethod]
[SoapHeader("Authentication", Direction = SoapHeaderDirection.In)]
public XmlDocument HelloWorld()
{
XmlDocument response = new XmlDocument();
try
{
//Boolean validateUser = Membership.ValidateUser(Authentication.Username, Authentication.Password);
if (Authentication != null)
{
response.LoadXml(String.Format("{0}{1}{2}", "<BOM>", "Hurray", "</BOM>"));
}
}
catch( Exception ex)
{
response.LoadXml(String.Format("{0}{1}{2}", "<Error>", ex.Message, "</Error>"));
}
return response;
}
}

The problem is with the client code:
Set the URI to the service URI (i.e. the asmx file)
Add the soap action as a header (i.e. HelloWorld)
Set the content type as text/xml
Change the soap request to include the namespace on the soap method and not the body element
Try this:
HttpWebRequest request;
string strSOAPRequestBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
" <soap:Header>" +
" <AuthHeader xmlns=\"http://tempuri.org/\">" +
" <Username>string</Username>" +
" <Password>string</Password>" +
" </AuthHeader>" +
" </soap:Header>" +
" <soap:Body>" +
" <HelloWorld xmlns=\"http://tempuri.org/\" />" +
" </soap:Body>" +
"</soap:Envelope>";
request = (HttpWebRequest)WebRequest.Create("http://localhost:1494/Service1.asmx");
request.Accept = "text/xml";
request.Method = "POST";
request.ContentType = "text/xml;charset=\"utf-8\"";
request.Headers.Add("SOAPAction", "\"http://tempuri.org/HelloWorld\"");
request.ContentLength = strSOAPRequestBody.Length;
using (Stream stream = request.GetRequestStream())
{
using (StreamWriter sw = new StreamWriter(stream))
{
sw.Write(strSOAPRequestBody);
sw.Flush();
}
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
{
Console.WriteLine((responseStream.ReadToEnd()));
}
}
If you do that you should receive the response:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3
.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body><HelloWorldResponse xmlns="http://tempuri.org/">
<HelloWorldResult>
<BOM xmlns="">Hurray</BOM>
</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>
To validate the username and password would depend on your implementation -- if you have asp.net membership then you should be able to use the ValidateUser method. Also note that if you are not using SSL then the username and password will be visible when sent over the wire.
Another note is that hand crafting XML as a string is almost always a bad idea so (at the very least) use XML framework classes to generate proper XML. Even better is to use web service toolkit.

Related

Created a Soap Webservice and calling it in asp.net uisng code and getting error of The remote name could not be resolved

I had developed one web service in SOAP format and trying to access service in asp.net using the below mentioned code.
public static void CallWebService()
{
try
{
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var _url = "https://test.in/ModelDetail/Service.asmx";
var _action = "https://test.in/ModelDetail/GetWarrantyDetails";
XmlDocument soapEnvelopeXml = CreateSoapEnvelope();
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
//using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
using (HttpWebResponse webResponse= (HttpWebResponse)webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
Console.Write(soapResult);
}
}
catch(Exception ex) { throw ex; }
}
private static HttpWebRequest CreateWebRequest(string url, string action)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
private static XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelop = new XmlDocument();
soapEnvelop.LoadXml(#"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:tem='https://ndb.bmw.in/'><soapenv:Header/><soapenv:Body><tem:GetWarrantyDetails><tem:IP><demono>WBA3Y37070D45</demono></tem:IP></tem:GetWarrantyDetails></soapenv:Body></soapenv:Envelope>");
return soapEnvelop;
}
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
but when i call this code i get error of The remote name could not be resolved.
Tried all method but get this error only.
What is missing or wrong i am doing?

passing custom object after serialization to WCF

I have a WCF service method with following signature:
public string CTNotification(JSONRecordingCompletedNotification content)
{
I want to create a client and consume it. I have written following code but it gives error:
using (StreamReader sr = new StreamReader(Server.MapPath("~/json.txt")))
{
string serviceBaseUrl = ConfigurationManager.AppSettings["serviceurl"].ToString() + "CTNotification";
string conversationId = ConfigurationManager.AppSettings["conversationId"].ToString();
String line = sr.ReadToEnd();
string jsonText = line;
string body = jsonText;
JSONRecordingCompletedNotification RecordingCompletedNotification = new JavaScriptSerializer().Deserialize<JSONRecordingCompletedNotification>(body);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceBaseUrl);
request.Method = "POST";
request.ContentType = "application/json";
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(RecordingCompletedNotification);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Label1.Text = response.ToString();
}
I get following error:
The remote server returned an error: (400) Bad Request.
i would suggest you to use either of the lib for json serialization and deserialization
json.net
fastjson
and change the content type as
request.ContentType = "application/json; charset=utf-8";

Programatically Login http://waec2013.com/waecexam/ in asp.net

Guys I try to login to http://waec2013.com/waecexam/ website by using
HttpWebRequest
CookieContainer
There is another technique I can use webbrowser but as this is web application so I cannot use webbrowser.
But no luck is this possible that I can login to that website and get the specific data?
I do reverse engineering and do some coding but not achieve my result.
Any Suggestions
string formUrl = "http://waec2013.com/waecexam/";
string formParams = string.Format("adminName={0}&adminPass={1}&act={2}",
"passwaec", "cee660","login");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
string pageSource;
string getUrl = "http://waec2013.com/waecexam/Leads.php";
WebRequest getRequest = WebRequest.Create(getUrl);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
Finally I have resolve my own question and post for you guys if you need it.
public class CookiesAwareWebClient : WebClient
{
public CookieContainer CookieContainer { get; private set; }
public CookiesAwareWebClient()
{
CookieContainer = new CookieContainer();
}
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
((HttpWebRequest)request).CookieContainer = CookieContainer;
return request;
}
}
using (var client = new CookiesAwareWebClient())
{
var values = new NameValueCollection
{
{ "adminName", "passwaec" },
{ "adminPass", "cee660" },
{ "x", "0" },
{ "y", "0" },
{ "act", "login" },
};
// We authenticate first
client.UploadValues("http://waec2013.com/waecexam/index.php", values);
// Now we can download
client.DownloadFile("http://waec2013.com/waecexam/leadExp.php?act=export",
#"c:\abc.txt");
}
Add this at the start of your method:
var cookies = new CookieContainer();
After each line where you create a webrequest assing the cookies to the instantiated request:
WebRequest req = WebRequest.Create(formUrl);
req.CookieContainer = cookies;
This will store any incoming cookies and send all cookies in the container to the webserver when GETing POSTing.
You don't need to use the Set-Cookie header in that case.

posting items from asp.net website to craigslist

here an example of posting to craigslist . http://www.craigslist.org/about/bulk_posting_interface in perl language.
any craigslist posting example in asp.net ?
I converted the perl example (from above link ) into asp.net but still generates an error , error is " The server committed a protocol violation. Section=ResponseStatusLine "
anyone have an idea about this. thanks in advance
here is my code ,
string xml = #"<?xml version='1.0'?><rdf:RDF xmlns='http://purl.org/rss/1.0/' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:cl='http://www.craigslist.org/about/cl-bulk-ns/1.0'> <channel><items><rdf:li rdf:resource='NYCBrokerHousingSample1'/><rdf:li rdf:resource='NYCBrokerHousingSample2'/> </items> <cl:auth username='fawad_ashfaq#hotmail.com' password='*******' accountID='14'/> </channel> <item rdf:about='NYCBrokerHousingSample1'> <cl:category>fee</cl:category> <cl:area>nyc</cl:area> <cl:subarea>mnh</cl:subarea> <cl:neighborhood>Upper West Side</cl:neighborhood> <cl:housingInfo price='1450' bedrooms='0' sqft='600'/> <cl:replyEmail privacy='C'>bulkuser#bulkposterz.net</cl:replyEmail> <cl:brokerInfo companyName='Joe Sample and Associates' feeDisclosure='fee disclosure here' /> <title>Spacious Sunny Studio in Upper West Side</title> <description><![CDATA[ posting body here ]]></description> </item> </rdf:RDF>";
string BASE_URL = "https://post.craigslist.org/bulk-rss/post";
HttpPost(BASE_URL, xml ); Private static string HttpPost(string url, string postData)
{
HttpWebRequest request = null;
Uri uri = new Uri(url);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
using (Stream writeStream = request.GetRequestStream())
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(postData);
writeStream.Write(bytes, 0, bytes.Length);
}
string result = string.Empty;
request.ProtocolVersion = System.Net.HttpVersion.Version10;
request.KeepAlive = false;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
using (System.IO.StreamReader readStream = new System.IO.StreamReader(responseStream, Encoding.UTF8))
{
result = readStream.ReadToEnd();
}
}
}
}
catch (Exception exp)
{
// MessageBox.Show(exp.Message);
}
return result;
} // end HttpPost
you can use Fiddle2(windows) or Charles(os x) to capture http request and response, compare the difference between the perl example and asp.net example, then you may find the 'bug'.
I got around this by adding
request.ProtocolVersion = System.Net.HttpVersion.Version10;

convert HTTP request code to HTTPS request code

I have got following code witch are sending xml file on HTTP protocol and getting response back as xml file from webserver and its working fine with HTTP protocol, but now i need to send such a XML file to HTTPS protocol (not http) and need to get response as xml file from it. the code to send xml file and get response from HTTP is :
string targetUri = "http://www.hostelspoint.com/xml/xml.php"; /*this will be like: "https://www.hostelspoint.com/xml/xml.php"*/
System.Xml.XmlDocument reqDoc = new System.Xml.XmlDocument();
reqDoc.Load(Server.MapPath("~\\getdetail.xml"));
string formParameterName = "OTA_request";
string xmlData = reqDoc.InnerXml;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(targetUri);
string sendString = formParameterName + "=" + HttpUtility.UrlEncode(xmlData);
//string sendString = HttpUtility.UrlEncode(xmlData);
byte[] byteStream;
byteStream = System.Text.Encoding.UTF8.GetBytes(sendString);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteStream.LongLength;
using (Stream writer = request.GetRequestStream())
{
writer.Write(byteStream, 0, (int)request.ContentLength);
writer.Flush();
}
HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
string respStr = "";
if (request.HaveResponse)
{
if (resp.StatusCode == HttpStatusCode.OK || resp.StatusCode == HttpStatusCode.Accepted)
{
StreamReader respReader = new StreamReader(resp.GetResponseStream());
respStr = respReader.ReadToEnd(); // get the xml result in the string object
XmlDocument doc = new XmlDocument();
doc.LoadXml(respStr);
Label1.Text = doc.InnerXml.ToString();
}
}
There shouldn't be much difference in your code, as HTTP or HTTPS differs only in transport level, not in application level.
What may become a problem here is, if the server certificate used in the targetUri is trusted on your server. In this case the HTTPS identity cannot be verified.

Resources