在工作中經常用到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 很難精確的控制服務的訪問。建議在實際開發中可以根據自己業務添加動態的驗證方式,和每個業務獨立的業務類型。這樣可以更加精確的控制訪問着的訪問權限和權限降級。
