在工作中经常用到webservice,在.net 开发中经常用到webservice,在java开发经常用到cxf.
今天闲置没事就介绍下 .net webservice中常用到 soapheader token验证和重载。当然在正常使用中不太建议使用重载。
下面的列表概述接收和处理 SOAP 标头的基本步骤:
-
创建一个从 SoapHeader 派生的类,表示传入 SOAP 标头的数据。
using System.Web.Services.Protocols; namespace WService { /// <summary> /// Fireran /// </summary> public class MySoapHeader : SoapHeader { public MySoapHeader() { } /// <summary> /// username /// </summary> public string UserName { get; set; } /// <summary> /// ip /// </summary> public string Ip { get; set; } /// <summary> /// token /// </summary> public string Token { get; set; } } }
2. XML Web services 方法将 myHeader 成员指定为 MemberName 属性,接收 XML Web services 方法的 MyHeader SOAP 标头的内容。
private MySoapHeader _mySoapHeader; public MySoapHeader mySoapHeader { get { return _mySoapHeader; } set { _mySoapHeader = value; } }
[WebMethod] [SoapHeader("mySoapHeader")] public string GetSayHello(long id) { string result = ""; if (mySoapHeader==null) { result = "token is nulll"; } else { if (mySoapHeader.Token.Equals("123456")) { result = "hello world" + id; } else { result = "token is err"; } } return result; }
3. 发布webservice 利用wsdl 工具生成代理类
//------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行时版本:2.0.50727.5466 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ using System; using System.ComponentModel; using System.Diagnostics; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Serialization; // // 此源代码由 wsdl 自动生成, Version=2.0.50727.3038。 // /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Web.Services.WebServiceBindingAttribute(Name="FireRanSoap", Namespace="http://fireran.org/")] public partial class FireRan : System.Web.Services.Protocols.SoapHttpClientProtocol { private System.Threading.SendOrPostCallback HelloWorldOperationCompleted; private MySoapHeader mySoapHeaderValueField; private System.Threading.SendOrPostCallback GetSayHelloOperationCompleted; private System.Threading.SendOrPostCallback GetSayHello1OperationCompleted; /// <remarks/> public FireRan() {this.Url = "http://localhost:54540/FireRan.asmx"; } public MySoapHeader MySoapHeaderValue { get { return this.mySoapHeaderValueField; } set { this.mySoapHeaderValueField = value; } } /// <remarks/> public event HelloWorldCompletedEventHandler HelloWorldCompleted; /// <remarks/> public event GetSayHelloCompletedEventHandler GetSayHelloCompleted; /// <remarks/> public event GetSayHello1CompletedEventHandler GetSayHello1Completed; /// <remarks/> [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://fireran.org/HelloWorld", RequestNamespace="http://fireran.org/", ResponseNamespace="http://fireran.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public string HelloWorld() { object[] results = this.Invoke("HelloWorld", new object[0]); return ((string)(results[0])); } /// <remarks/> public System.IAsyncResult BeginHelloWorld(System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("HelloWorld", new object[0], callback, asyncState); } /// <remarks/> public string EndHelloWorld(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); } /// <remarks/> public void HelloWorldAsync() { this.HelloWorldAsync(null); } /// <remarks/> public void HelloWorldAsync(object userState) { if ((this.HelloWorldOperationCompleted == null)) { this.HelloWorldOperationCompleted = new System.Threading.SendOrPostCallback(this.OnHelloWorldOperationCompleted); } this.InvokeAsync("HelloWorld", new object[0], this.HelloWorldOperationCompleted, userState); } private void OnHelloWorldOperationCompleted(object arg) { if ((this.HelloWorldCompleted != null)) { System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); this.HelloWorldCompleted(this, new HelloWorldCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); } } /// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("MySoapHeaderValue")] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://fireran.org/SayHello", RequestElementName="SayHello", RequestNamespace="http://fireran.org/", ResponseElementName="SayHelloResponse", ResponseNamespace="http://fireran.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] [return: System.Xml.Serialization.XmlElementAttribute("SayHelloResult")] public string GetSayHello(long id) { object[] results = this.Invoke("GetSayHello", new object[] { id}); return ((string)(results[0])); } /// <remarks/> public System.IAsyncResult BeginGetSayHello(long id, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("GetSayHello", new object[] { id}, callback, asyncState); } /// <remarks/> public string EndGetSayHello(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); } /// <remarks/> public void GetSayHelloAsync(long id) { this.GetSayHelloAsync(id, null); } /// <remarks/> public void GetSayHelloAsync(long id, object userState) { if ((this.GetSayHelloOperationCompleted == null)) { this.GetSayHelloOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetSayHelloOperationCompleted); } this.InvokeAsync("GetSayHello", new object[] { id}, this.GetSayHelloOperationCompleted, userState); } private void OnGetSayHelloOperationCompleted(object arg) { if ((this.GetSayHelloCompleted != null)) { System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); this.GetSayHelloCompleted(this, new GetSayHelloCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); } } /// <remarks/> [System.Web.Services.Protocols.SoapHeaderAttribute("MySoapHeaderValue")] [System.Web.Services.WebMethodAttribute(MessageName="GetSayHello1")] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://fireran.org/SayHello1", RequestElementName="SayHello1", RequestNamespace="http://fireran.org/", ResponseElementName="SayHello1Response", ResponseNamespace="http://fireran.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] [return: System.Xml.Serialization.XmlElementAttribute("SayHello1Result")] public string GetSayHello(int id, int name) { object[] results = this.Invoke("GetSayHello1", new object[] { id, name}); return ((string)(results[0])); } /// <remarks/> public System.IAsyncResult BeginGetSayHello1(int id, int name, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("GetSayHello1", new object[] { id, name}, callback, asyncState); } /// <remarks/> public string EndGetSayHello1(System.IAsyncResult asyncResult) { object[] results = this.EndInvoke(asyncResult); return ((string)(results[0])); } /// <remarks/> public void GetSayHello1Async(int id, int name) { this.GetSayHello1Async(id, name, null); } /// <remarks/> public void GetSayHello1Async(int id, int name, object userState) { if ((this.GetSayHello1OperationCompleted == null)) { this.GetSayHello1OperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetSayHello1OperationCompleted); } this.InvokeAsync("GetSayHello1", new object[] { id, name}, this.GetSayHello1OperationCompleted, userState); } private void OnGetSayHello1OperationCompleted(object arg) { if ((this.GetSayHello1Completed != null)) { System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); this.GetSayHello1Completed(this, new GetSayHello1CompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); } } /// <remarks/> public new void CancelAsync(object userState) { base.CancelAsync(userState); } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fireran.org/")] [System.Xml.Serialization.XmlRootAttribute(Namespace="http://fireran.org/", IsNullable=false)] public partial class MySoapHeader : System.Web.Services.Protocols.SoapHeader { private string userNameField; private string passWordField; private string tokenField; private System.Xml.XmlAttribute[] anyAttrField; /// <remarks/> public string UserName { get { return this.userNameField; } set { this.userNameField = value; } } /// <remarks/> public string PassWord { get { return this.passWordField; } set { this.passWordField = value; } } /// <remarks/> public string Token { get { return this.tokenField; } set { this.tokenField = value; } } /// <remarks/> [System.Xml.Serialization.XmlAnyAttributeAttribute()] public System.Xml.XmlAttribute[] AnyAttr { get { return this.anyAttrField; } set { this.anyAttrField = value; } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void HelloWorldCompletedEventHandler(object sender, HelloWorldCompletedEventArgs e); /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class HelloWorldCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; internal HelloWorldCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } /// <remarks/> public string Result { get { this.RaiseExceptionIfNecessary(); return ((string)(this.results[0])); } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void GetSayHelloCompletedEventHandler(object sender, GetSayHelloCompletedEventArgs e); /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class GetSayHelloCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; internal GetSayHelloCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } /// <remarks/> public string Result { get { this.RaiseExceptionIfNecessary(); return ((string)(this.results[0])); } } } /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] public delegate void GetSayHello1CompletedEventHandler(object sender, GetSayHello1CompletedEventArgs e); /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class GetSayHello1CompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; internal GetSayHello1CompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } /// <remarks/> public string Result { get { this.RaiseExceptionIfNecessary(); return ((string)(this.results[0])); } } }
4. 在代理类中添加 token 信息 修改代理类中的构造方法 如下
public FireRan() {
MySoapHeaderValue = new MySoapHeader();
this.MySoapHeaderValue.Token = "123456";
this.Url = "http://localhost:54540/FireRan.asmx";
}
5. 添加测试类进行测试
[TestFixture] public class FireRanTest { [Test] public void Read() { using(FireRan fireRan = new FireRan()) { Console.Write(fireRan.GetSayHello(1)); } } }
6. 运行结果
在项目中为了服务安全对token和ip进行授权是很有必要的。但是在项目中有发现token 和 ip 很难精确的控制服务的访问。建议在实际开发中可以根据自己业务添加动态的验证方式,和每个业务独立的业务类型。这样可以更加精确的控制访问着的访问权限和权限降级。