Depends on the level of security needed. Calling from jQuery does open up your code to inspection, and can be insecure. One option is to use a proxy page which is called from jQuery, and then the proxy page communicates with the webservice. At that point the proxy page can be set up to limit access based on calling ip, host, hidden form field value, etc.
Another recommendation is to Base64 encode all request parameters. Not super secure, but entails more work for prying eyes to decode.
If your form is secure (e.g. requires a login to access), passing the current user id to the webservice and then performing a lookup to determine if that user exists within the webservice prior to performing any additional processing is the most ideal.
Webservices being what they are, are open to the public. Using credentials to access if the information returned is secure is a must. However doing from jQuery if you do not have any restrictions (e.g. login to access calling page), it will always be vulnerable.
These are only options. Hope it helps.
=================Appended Example:
Proxy Page (.aspx)
protected void Page_Load(object sender, EventArgs e) {
string result = "";
if (Request.QueryString["srvcmethod"] != null && Request.QueryString["encodedJSONdata"] != null) {
string decodedJSONRequest = encoder.StringFromBase64(Request.QueryString["encodedJSONdata"].ToString().Trim());
string wsdlData = GetWebservice("ccAddressAPI", Request.QueryString["srvcmethod"].ToString().Trim(), decodedJSONRequest);
/*
* Existance of QueryString('callback') indicates a request initiated from JQuery AJAX on remote server
* response must be formatted as JSONP to prevent parse failure (eg 'callback(JSON);' )
*/
if (Request.QueryString["callback"] != null) {
string jsonpCallBack = Request.QueryString["callback"];
result = jsonpCallBack + "(" + wsdlData + ");";
} else {
result = wsdlData;
}
Response.Write(result);
Response.End();
}
}
/// <summary>
/// Performs post to WebService
/// </summary>
/// <param name="srvc">Service File Name</param>
/// <param name="srvcMethod">Method within service to call</param>
/// <param name="jsonData">JSON Serialized form data</param>
/// <returns>JSON Serialized string of webservice response</returns>
private string GetWebservice(string srvc, string srvcMethod, string jsonData) {
string result = null;
string wsdlData = null;
Dictionary<string, object> obj = new Dictionary<string, object>();
//--define webservice url
string currentReq = Request.Url.GetLeftPart(UriPartial.Authority);
string servicepath = "/websrvc/";
string wsdl = currentReq + servicepath + srvc + ".svc/" + srvcMethod;
//--initiate webservice request
try {
byte[] postData = Encoding.UTF8.GetBytes(jsonData);
WebRequest request = WebRequest.Create(wsdl);
request.Method = WebRequestMethods.Http.Post;
request.ContentLength = postData.Length;
request.ContentType = "text/json";
Stream dataStream = request.GetRequestStream();
dataStream.Write(postData, 0, postData.Length);
dataStream.Close();
//--retrieve/store request response
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
wsdlData = reader.ReadToEnd();
reader.Close();
response.Close();
} catch (Exception ex) {
logErrors(ex, System.Reflection.MethodBase.GetCurrentMethod().Name);
}
return wsdlData;
}
jQuery example to call proxy page
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(input){var output="";var chr1,chr2,chr3,enc1,enc2,enc3,enc4;var i=0;input=Base64._utf8_encode(input);while(i<input.length){chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else if(isNaN(chr3)){enc4=64}output=output+this._keyStr.charAt(enc1)+this._keyStr.charAt(enc2)+this._keyStr.charAt(enc3)+this._keyStr.charAt(enc4)}return output},decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i<input.length){enc1=this._keyStr.indexOf(input.charAt(i++));enc2=this._keyStr.indexOf(input.charAt(i++));enc3=this._keyStr.indexOf(input.charAt(i++));enc4=this._keyStr.indexOf(input.charAt(i++));chr1=(enc1<<2)|(enc2>>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output=output+String.fro mCharCode(chr1);if(enc3!=64){output=output+String.fromCharCode(chr2)}if(enc4!=64){output=output+String.fromCharCode(chr3)}}output=Base64._utf8_decode(output);return output},_utf8_encode:function(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n<string.length;n++){var c=string.charCodeAt(n);if(c<128){utftext+=String.fromCharCode(c)}else if((c>127)&&(c<2048)){utftext+=String.fromCharCode((c>>6)|192);utftext+=String.fromCharCode((c&63)|128)}else{utftext+=String.fromCharCode((c>>12)|224);utftext+=String.fromCharCode(((c>>6)&63)|128);utftext+=String.fromCharCode((c&63)|128)}}return utftext},_utf8_decode:function(utftext){var string="";var i=0;var c=c1=c2=0;while(i<utftext.length){c=utftext.charCodeAt(i);if(c<128){string+=String.fromCharCode(c);i++}else if((c>191)&&(c<224)){c2=utftext.charCodeAt(i+1);string+=String.fromCharCode(((c&31)<<6)|(c2&63));i+=2}else{c2=utftext.charCodeAt(i+1);c3=utftext.charCodeAt(i+2);string+=String.fromCharCode(((c&15)<<12)|((c2&63)<<6)|(c3&63));i+=3}}return strin g}}
var data = JSON.stringify({
"EmployeeId": EmployeeId,
"LoginAccountId": LoginAccountId,
"CustomerId": CustomerId,
"CostCentreId": CostCentreId,
"ParentCostCentreId": ParentCostCentreId,
"CostCentreAdministratorId": CostCentreAdministratorId,
"UserType": UserType,
"optionValList": optionValList
});
var jsondata = Base64.encode(data);
var srvcmethod = 'initCostCentreAddressDataProvider';
$.ajax({
url: "[proxypageurl.aspx]",
type: "GET",
cache: false,
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
data: { "srvcmethod": srvcmethod, "encodedJSONdata": jsondata },
error: function (XMLHttpRequest, textStatus, errorThrown) { console.log({ 'XMLHttpRequest': XMLHttpRequest, 'textStatus': textStatus, 'errorThrown': errorThrown }); },
success: function (jsonRes) {
var json = JSON.parse(jsonRes);
//additional processing here
}
});
I hate to answer a question with a question, but what is the security need that you have, and what return type is the service responding with?
Calling a web method from the code behind is more self contained. The only notable difference is that the web method is typically only accessed from the calling page or application and unless you are formatting the response as JSONP, would not be available from other domains. A web service is publicly available and by default usually returns XML, but if you are returning JSON from the webservice, it also would not be available to other domains, only to yours.
So maybe format your response from the webservice as JSON? At that point, even if I know about your service I can't call it, unless you format as JSONP.
The above example uses JSONP for the jQuery as my webservice is on a seperate domain from the calling page. This can be modified to just return JSON, and the serverside logic should still work (however it is UNTESTED in that use case).
Hope that helps a little.