在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 >= )
{
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的用户名+密码认证方式(转)

    概述 今天在做Master Data Service(后面简称MDS)项目时需要通过WCF来使用MDS的API,从而对MDS的数据进行操作.在这个过程中,遇到了一个棘手的问题,就是在客户端调用Web ...

  2. WCF身份验证之用户名密码认证

    WCF支持多种认证技术,例如Windowns认证.X509证书.Issued Tokens.用户名密码认证等,在跨Windows域分布的系统中,用户名密码认证是比较常用的,要实现用户名密码认证,就必须 ...

  3. Nginx实战之让用户通过用户名密码认证访问web站点

    1.Nginx实战之让用户通过用户名密码认证访问web站点 [root@master ~]# vim /usr/local/nginx/conf/extra/www.conf server { lis ...

  4. nginx让用户通过用户名密码认证访问web页面

    在使用nginx转发的时候,要进行一次用户身份的确认. 1)通过htpasswd命令生成用户名及对应密码数据库文件. [root@bgs-5p173-wangwenting ~]# htpasswd ...

  5. 启动Nginx目录浏览功能及 让用户通过用户名密码认证访问web站点

    一.启动Nginx目录浏览功能  [root@abcdocker extra]# cat w.conf server { listen 80; server_name IP地址; location / ...

  6. Geoserver通过ajax跨域访问服务数据的方法(含用户名密码认证的配置方式)

    Goeserver数据有两种,一种需进行用户密码的权限认证,一种无须用户密码.对于网上跨域访问Geoserver数据的种种方法,对这2种数据并非通用. 笔者将Geoserver官方下载的Geoserv ...

  7. WCF之添加自定义用户名密码认证

    1.创建WCF服务应用以及调用客户端(请自行google).  2.创建X509证书       cmd 进入  C:\Program Files\Microsoft SDKs\Windows\v6. ...

  8. Nginx之让用户通过用户名密码认证访问web站点

    有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问. 那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那 ...

  9. squid添加用户名密码认证

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

随机推荐

  1. How to compare dates in Java

    How to compare dates in JavaBy mkyong | January 18, 2010 | Updated : November 15, 2016 | Viewed : 93 ...

  2. C#基础第一天-作业答案

    题一答案: Console.WriteLine("请输入a"); int a = Convert.ToInt32(Console.ReadLine()); Console.Writ ...

  3. office2010激活 错误代码0X8007000D,KMS激活0x8007000D错误解决办法,亲测成功激活

    只针对VL版本 注意:此方法只对VL版本的,或者是MSDN版本通过替换文件转为VL版本的Office2010有效.零售版本的就别指望KMS激活了. 怎么看自己是不是VL版本的,只要看帮助里面激活的地方 ...

  4. 谈谈MySQL的WriteSet并行复制

    [历史背景] 岁月更迭中我已经从事MySQL-DBA这个工作三个年头,见证MySQL从“基本可用”,“边缘系统可以用MySQL”,“哦操!你怎么不用MySQL”; 正所谓!“一个数据库的境遇既取决于历 ...

  5. redis 3.2.3的源码安装

    Install necessary packages On CentOS : yum install wget make gcc tcl On CentOS yum install wget make ...

  6. The superclass "javax.servlet.http.HttpServlet" was not found 问题解决

    项目中报" The superclass "javax.servlet.http.HttpServlet" was not found "这个错误,是因为缺少t ...

  7. android sqlite3:数据库操作

    1. 修改表名: alter table notification rename to notification_test 2. 修改数据库名称: 3. 复制一个表的数据到另外一个表中(表的字段一致) ...

  8. Atitit  404错误的排查流程总结 v3 qaf

    Atitit  404错误的排查流程总结 v3 qaf 1.1. 用了注解不生效 提示404 Not Found1 1.2. 路径不对了,开头多了个空格1 2. 500 Servlet Excepti ...

  9. struts2(五) s标签和国际化

    坚持就是胜利. --WH 一.s标签 在struts-2.3.15.1/docs/WW/docs/tag-reference.html下,就有着struts2所有标签的参考文献,只能看看其中比较常用的 ...

  10. 细说php(二) 变量和常量

    一. 变量的声明 1. php中声明变量的方法:  $var = 123; 2. php是弱类型的语言, 变量的类型由存储的值决定 注: Java是强类型语言, 声明变量一定要先指定类型 二. 变量的 ...