【WCF安全】SOAP消息实现用户名验证:通过OperationContext直接添加/访问MessageHeader信息
服务代码
1.契约
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.Serialization; 5 using System.ServiceModel; 6 using System.ServiceModel.Web; 7 using System.Text; 8 9 namespace 消息拦截实现用户名验证 10 { 11 [ServiceContract(Namespace="http://localhost/")] 12 public interface IService1 13 { 14 [OperationContract] 15 string GetData(int value); 16 17 } 18 }
2.服务实现
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.Serialization; 5 using System.ServiceModel; 6 using System.ServiceModel.Web; 7 using System.Text; 8 9 namespace 消息拦截实现用户名验证 10 { 11 public class Service1 : IService1 12 { 13 public string GetData(int value) 14 { 15 string msg = OperationContext.Current.RequestContext.RequestMessage.ToString(); 16 // 注意namespace必须和ServiceContract中定义的namespace保持一致,默认是:http://tempuri.org 17 var ns = "http://localhost/"; 18 var user = GetHeaderValue("user", ns); 19 var pwd = GetHeaderValue("pwd", ns); 20 // 验证失败 21 if (user != "Guest01" || pwd != "123") 22 return msg += "/r/n用户名密码错误"; 23 return msg += "/r/n" + string.Format("You entered: {0}", value); 24 } 25 private string GetHeaderValue(string name, string ns = "http://tempuri.org") 26 { 27 var headers = OperationContext.Current.IncomingMessageHeaders; 28 var index = headers.FindHeader(name, ns); 29 if (index > -1) 30 return headers.GetHeader<string>(index); 31 else 32 return null; 33 } 34 } 35 }
3.服务配置(Demo中采用的是默认配置)
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <system.web> 4 <compilation debug="true" targetFramework="4.0" /> 5 </system.web> 6 <system.serviceModel> 7 <behaviors> 8 <serviceBehaviors> 9 <behavior> 10 <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 --> 11 <serviceMetadata httpGetEnabled="true"/> 12 <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --> 13 <serviceDebug includeExceptionDetailInFaults="false"/> 14 </behavior> 15 </serviceBehaviors> 16 </behaviors> 17 <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 18 </system.serviceModel> 19 <system.webServer> 20 <modules runAllManagedModulesForAllRequests="true"/> 21 </system.webServer> 22 </configuration>
客户端
1.客户端代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel.Channels; using System.ServiceModel; namespace 客户端 { class Program { static void Main(string[] args) { try { SR01.Service1Client sc = new SR01.Service1Client(); using (var scope = new OperationContextScope(sc.InnerChannel)) { // 注意namespace必须和ServiceContract中定义的namespace保持一致,默认是:http://tempuri.org var myNamespace = "http://localhost/"; // 注意Header的名字中不能出现空格,因为要作为Xml节点名。 var user = MessageHeader.CreateHeader("user", myNamespace, "Guest01"); var pwd = MessageHeader.CreateHeader("pwd", myNamespace, "123"); OperationContext.Current.OutgoingMessageHeaders.Add(user); OperationContext.Current.OutgoingMessageHeaders.Add(pwd); string res = sc.GetData(1); Console.WriteLine(res); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadLine(); } } }
2.客户端配置
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <system.serviceModel> 4 <bindings> 5 <basicHttpBinding> 6 <binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00" 7 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 8 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 9 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 10 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 11 useDefaultWebProxy="true"> 12 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 13 maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 14 <security mode="None"> 15 <transport clientCredentialType="None" proxyCredentialType="None" 16 realm="" /> 17 <message clientCredentialType="UserName" algorithmSuite="Default" /> 18 </security> 19 </binding> 20 </basicHttpBinding> 21 </bindings> 22 <client> 23 <endpoint address="http://localhost:7105/Service1.svc" binding="basicHttpBinding" 24 bindingConfiguration="BasicHttpBinding_IService1" contract="SR01.IService1" 25 name="BasicHttpBinding_IService1" /> 26 </client> 27 </system.serviceModel> 28 </configuration>
返回结果:
红框部分为正常返回值;其它部分为SOAP XML内容