WCF安全:通过 扩展实现用户名密码认证
在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安全:通过 扩展实现用户名密码认证的更多相关文章
- WCF的用户名+密码认证方式(转)
概述 今天在做Master Data Service(后面简称MDS)项目时需要通过WCF来使用MDS的API,从而对MDS的数据进行操作.在这个过程中,遇到了一个棘手的问题,就是在客户端调用Web ...
- WCF身份验证之用户名密码认证
WCF支持多种认证技术,例如Windowns认证.X509证书.Issued Tokens.用户名密码认证等,在跨Windows域分布的系统中,用户名密码认证是比较常用的,要实现用户名密码认证,就必须 ...
- Nginx实战之让用户通过用户名密码认证访问web站点
1.Nginx实战之让用户通过用户名密码认证访问web站点 [root@master ~]# vim /usr/local/nginx/conf/extra/www.conf server { lis ...
- nginx让用户通过用户名密码认证访问web页面
在使用nginx转发的时候,要进行一次用户身份的确认. 1)通过htpasswd命令生成用户名及对应密码数据库文件. [root@bgs-5p173-wangwenting ~]# htpasswd ...
- 启动Nginx目录浏览功能及 让用户通过用户名密码认证访问web站点
一.启动Nginx目录浏览功能 [root@abcdocker extra]# cat w.conf server { listen 80; server_name IP地址; location / ...
- Geoserver通过ajax跨域访问服务数据的方法(含用户名密码认证的配置方式)
Goeserver数据有两种,一种需进行用户密码的权限认证,一种无须用户密码.对于网上跨域访问Geoserver数据的种种方法,对这2种数据并非通用. 笔者将Geoserver官方下载的Geoserv ...
- WCF之添加自定义用户名密码认证
1.创建WCF服务应用以及调用客户端(请自行google). 2.创建X509证书 cmd 进入 C:\Program Files\Microsoft SDKs\Windows\v6. ...
- Nginx之让用户通过用户名密码认证访问web站点
有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问. 那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那 ...
- squid添加用户名密码认证
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...
随机推荐
- Objective-C如何使用对象集合学习系列之一
本章介绍如何通过 Foundation 框架使用 Objective-C 处理数组与字典.本章内容: ● 使用 NSArray 与 NSMutableArray 创建数组 ● 在数组中添加.删除与 ...
- 转: FFmpeg功能命令汇总
原文: FFmpeg功能命令汇总 前言 如此强大的FFmpeg,能够实现视频采集.视频格式转化.视频截图.视频添加水印.视频切片.视频录制.视频推流.更改音视频参数功能等.通过终端命令如何实现这些功能 ...
- Mac下 如何配置虚拟机软件Parallel Desktop--超详细
Mac下 如何配置虚拟机软件Pparallel Desktop--超详细 Mac 的双系统解决方案有两种,一种是使用Boot Camp分区安装独立的Windows,一种是通过安装Parallels D ...
- Android自己定义ViewGroup(二)——带悬停标题的ExpandableListView
项目里要加一个点击可收缩展开的列表,要求带悬停标题,详细效果例如以下图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fon ...
- [LeetCode] Shortest Word Distance I & II & III
Shortest Word Distance Given a list of words and two words word1 and word2, return the shortest dist ...
- android源码上面开发App
使用eclipse 打开源码:http://blog.csdn.net/androidlover1991/article/details/17011991 使用android studio 打开源码h ...
- Java实现单链表翻转
单链表翻转比方有例如以下链表: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoaXp0eQ==/font/5a6L5L2T/fontsize ...
- 如何正确的重写equals() 和 hashCode()方法
比较两个Java对象时, 我们需要覆盖equals和 hashCode. public class User{ private String name; private int age; priva ...
- poj 1868 Antiarithmetic? 推断序列中是否有等差子序列
#include<iostream> using namespace std; const int maxN=10024; int n,vis[maxN],a[maxN]; bool fi ...
- C++类中的成员函数和构造函数为模板函数时的调用方法
所谓模板函数其实就是建立一个通用函数,这个通用函数的形参类型不具体指定,用一个虚拟类型来代表,这个通用函数就被称为函数模板. 例: #include <iostream> using na ...