【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内容

 

posted @ 2014-10-09 15:26  J.Y  阅读(703)  评论(0编辑  收藏  举报