WCF安全:通过 扩展实现用户名密码认证

摘要:
用户名和密码将自动附加到客户端上的SOAP消息。用于附加调用者的帐户和密码信息publicclassClientMessageInspector:request。标题。添加(pwdNameHeader);

  在webSservice时代,可以通过SOAPHEADER的方式很容易将用户名、密码附加到SOAP header消息头上,用户客户端对调用客户端身份的验证。在WCF 时代,也可以通过OperationContext.Current.IncomingMessageHeaders的方式将用户名、密码附加到SOAP消息中。但是这种方式实现起来有个缺点;那就是所有调用客户端都需要这样做才能将我们需要通过认证的帐号、密码附加到SOAP消息上。实际上,也可以通过WCF扩展的方式,在客户端自动将用户名、密码附加到SOAP消息中。这即是本文主题。

1、客户端消息自动附加用户名、密码
  实现IClientMessageInspector接口,用于附加调用者的账号、密码信息

 public class ClientMessageInspector : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            MessageHeader userNameHeader = MessageHeader.CreateHeader("OperationUserName", "http://tempuri.org", "account", false, "");
            MessageHeader pwdNameHeader = MessageHeader.CreateHeader("OperationPwd", "http://tempuri.org", "password", false, "");
            request.Headers.Add(userNameHeader);
            request.Headers.Add(pwdNameHeader);
            Console.WriteLine(request);
            return null;
        }
    }

2、实现IEndpointBehavior 接口。用户将客户端的消息检查器添加到clientruntime的消息检查器集合中.注意,以下代码中为了简单将服务端分发消息检查器也添加到服务端终结点分发器(EndpointDispatcher)的分发运行时的消息检查器中。

public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new ClientMessageInspector());//客户端使用
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MessageDispatcher());//服务端使用
        }

        public void Validate(ServiceEndpoint endpoint)
        {
            
        }

3、实现抽象类BehaviorextensionElement.用于在配置文件中配置对WCF服务行为的扩展

 internal class MessageBindingElement : BehaviorExtensionElement
    {
        public override Type BehaviorType
        {
            get { return typeof (MessageEndpointBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new MessageEndpointBehavior();
        }
    }

4、服务端验证客户端的账号、密码

实现IDispatcherMessageInspector

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            Console.WriteLine(request);
            string userName = GetHeaderValue("OperationUserName");
            string pwd = GetHeaderValue("OperationPwd");
            if ("account" == userName && "password" == pwd)
            {
                return null;
            }
            throw new Exception("用户名、密码错误");
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            
        }

        string GetHeaderValue(string key)
        {
            int index = OperationContext.Current.IncomingMessageHeaders.FindHeader(key, "http://tempuri.org");
            if (index >= 0)
            {
                return OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(index).ToString();
            }
            return null;
        }

5、服务端配置;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="messageInterptor" type="MessageInterceptor.MessageBindingElement,MessageInterceptor"/>
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="messageBehavior">
          <messageInterptor />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>      
      <service name="Services.CalculatorService">
        <endpoint address="net.tcp://127.0.0.1:8081/CalculateService" 
                  binding="netTcpBinding" 
                  contract="Contracts.ICalculator" 
                  behaviorConfiguration="messageBehavior"></endpoint>
      </service>
    </services>
  </system.serviceModel>
</configuration>

6、客户端配置;

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint name="calculatorService"
                address="net.tcp://127.0.0.1:8081/CalculateService"
                binding="netTcpBinding"
                contract="Contracts.ICalculator" 
                behaviorConfiguration="messageBehavior">
      </endpoint>
    </client>
    <extensions>
      <behaviorExtensions>
        <add name="messageInterptor" type="MessageInterceptor.MessageBindingElement,MessageInterceptor"/>
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="messageBehavior">
          <messageInterptor />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

7、运行结果图;

服务端;

WCF安全:通过 扩展实现用户名密码认证第1张

客户端;

WCF安全:通过 扩展实现用户名密码认证第2张

免责声明:文章转载自《WCF安全:通过 扩展实现用户名密码认证》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇如何用Android Studio同时使用SVN和Git管理项目Java中File类如何扫描磁盘所有文件包括子目录及子目录文件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

为CDH 5.7集群添加Kerberos身份验证及Sentry权限控制

转载请注明出处:http://www.cnblogs.com/xiaodf/ 4. 为CDH 5集群添加Kerberos身份验证 4.1 安装sentry1、点击“操作”,“添加服务”;2、选择sentry,并“继续”; 3、选择一组依赖关系 4、确认新服务的主机分配 5、配置存储数据库;  在mysql中创建对应用户和数据库: mysql>cre...

开发者分享 | 从零开始开发一个即时通讯项目

关于聊天室项目 聊天室项目,也被称为即时通讯(IM)。 其原理是服务器是一直在启动状态的线程,不断的从客户端(App)获取消息,收到消息后,进行类型和发送目标判断,以发送到群组或者单聊的方式,客户端收到消息后进行界面的展示。 如果要自己开发即时通讯类的 App,那么必须得要后台,但是现在很多第三方工具已经给我们集成好了所有需要调用的接口工具。 比如极光 I...

bootstrap-table的一些基本使用及表内编辑的实现

最近工作需要接触了bootstrap-table 所以研究了一下,并做了笔记,红色位置要特别注意  前端主要使用了 jquery bootstrap-table  bootstrap-edittable  bootstrap-table-edittable.js   1)首页我们需要先引用css及js文件 <!---bootstrap使用的是3--&...

GitLab 后台修改用户密码

GitLab 后台修改用户密码 # 打开控制台 gitlab-rails console production # 找到用户,输入密码,确认密码,保存 user = User.find_by(username: 'zhangsan') user.password = '12345678' user.password_confirmation = '123...

WebSocket以及socketIO的使用

简介 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。 现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出H...

HTTPUTILS

maven依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version>...