在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. mysql获取group by的总记录行数方法

    mysql获取group by内部可以获取到某字段的记录分组统计总数,而无法统计出分组的记录数. mysql的SQL_CALC_FOUND_ROWS 使用 获取查询的行数 在很多分页的程序中都这样写: ...

  2. List遍历Java 8 Streams map() examples

    1. A List of Strings to Uppercase 1.1 Simple Java example to convert a list of Strings to upper case ...

  3. linux上NFS性能参数

    linux nfs客户端对于同时发起的NFS请求数量进行了控制,若该参数配置较小会导致IO性能较差,查看该参数: cat /proc/sys/sunrpc/tcp_slot_table_entries ...

  4. Traefik Kubernetes 初试

    traefik 是一个前端负载均衡器,对于微服务架构尤其是 kubernetes 等编排工具具有良好的支持:同 nginx 等相比,traefik 能够自动感知后端容器变化,从而实现自动服务发现:今天 ...

  5. [Contiki系列论文之2]WSN的自适应通信架构

    说明:本系列文章翻译自Contiki之父Adam Dunkels经典论文,版权归原作者全部. Contiki是由Adam Dunkels及其团队开发的系统.研读其论文是对深入理解Contiki系统的最 ...

  6. Openfire更新服务器名称的方法

    转自:http://blog.csdn.net/vikione/article/details/5996932 Openfire更新服务器名称的方法: 1.登陆openfire管理页面,在主页面下方选 ...

  7. 分布式缓存Memcache和Redis

    引言 针对于如今计算机的CPU和网络设施,相应用程序来说,运行效率的瓶颈.已经不是代码的长度(实现同一个功能)和带宽了,而是,代码訪问资源的过程.即:让我们的程序慢下来的罪魁祸首就是IO操作. 程序从 ...

  8. 此编译单元不包含在frame元数据中指定的factoryClass,无法加载配置的运行时共享库

    警告:此编译单元不包含在frame元数据中指定的factoryClass,无法加载配置的运行时共享库.要在没有运行时共享库的情况下进行编译,请将 -static-link-runtime-shared ...

  9. 【架构】MVC模式

    架构模式 如何设计一个程序的结构,这是一门专门的学问,叫做"架构模式"(architectural pattern),属于编程的方法论. MVC模式就是架构模式的一种,它不仅适用于 ...

  10. 使用MSYS、Notepad++搭建C/C++开发环境

    目标说明 本文的目标是教会大家如何用Notepad++来编写C/C++代码,并能够编译运行. 注:Notepad++是一个非常优秀的开源文本编辑器.官网地址 http://notepad-plus-p ...