WCF身份验证二:基于消息安全模式的自定义身份验证
使用X509证书进行身份验证应该说是WCF安全模型中最”正常”的做法, 因为WCF强制要求使用证书加密身份数据, 离开了证书, 所有的身份验证机制拒绝工作, WCF支持的身份验证机制也相当复杂, 这里仅为了让程序按照我们的期望动起来, 所以并不展开讨论其它的验证方法, 有了一种做法做为基础, 也很容易查到其它的实现方法.
1. 本文所使用的软件环境: windows 7 Visual studio 2010
2. 用vs创建一个"WCF Service Library” 项目, 此时生成一个默认的IService1接口, 一个默认的GetData函数. 在当前解决方案中再增加一个Windows Forms Application项目, 作为服务的测试客户端, 直接在client中添加服务引用, 然后discover一下, Service1就显示出来了, 直接确定.
3. 现在开始写代码, 在client的form上放一个按钮, 在此按钮的点击事件中写上对服务的调用:
var proxy = new ServiceReference1.Service1Client();
MessageBox.Show(proxy.GetData(0));
把client项目设为起始项目, F5运行, 点击按钮:
4. 测试完成, 我们的基础环境没有任何问题. 现在开始考虑身份验证的问题, 首先, 我们采用用户名/密码的模式进行验证, 这就需要有一个验证用户名密码的地方: 在服务项目中添加引用System.IdentityModel, 然后向服务添加一个类, 这里将此类命名为Validator, 这个类的实现如下:
class Validator : System.IdentityModel.Selectors.UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName != "u" || password != "p")
throw new UnauthorizedAccessException();
}
}
然后右击服务项目的app.config, 选择Edit WCF Configuration.
5. 为默认的EndPoint创建一个binding configuration.
在左侧列表中选中顶级节点services, 右侧就会列出当前的endpoint, 如图所示, 默认有两个, 其中下面那个是元数据的endpoint, 我们不去管它, 上面那个endpoint的binding configuration后面有一个”click to create” 的link, 点击, 自动创建一个binding config, 创建完成以后, 切换到security标签:
将MessageClientCredentialType改为UserName, 如上图所示.
6. 为Service创建一个behavior
如下图所示:
在左侧panel的Advanced/Service behaviors下面默认有一个Empty name的节点, 先给它起个名字, 这里我是在服务的全名后面加了个Behavior后缀, 然后点击add按钮, 增加一个serviceCredential节点. 然后配置这个新增加的service credential:
在左侧列表中选中serviceCredential下面的serviceCertificate, 对其具体的值做如上配置:
(1) FindValue改为MyTestCert, 这是我们测试证书的名字, 一会儿我们会制作一个这个名字的证书, 导入电脑中.
(2) StoreName改为TrustedPeople
(3) X509FindType改为FindBySubjectName.
7. 使用我们刚才创建的Validator类
选中serviceCredential节点, 配置一下我们的自定义验证类:
其中CustomUserNamePasswordValidatoryType属性的值是:"WcfServiceLibrary3.Validator,WcfServiceLibrary3”, 前一个WcfServiceLibrary3是命名空间名, 后一个是程序集名, 不可省略. 然后将UserNamePasswordValidationMode设成Custom.
8. 将创建的behavior与服务进行关联.
在左侧面板中选中我们创建的服务Service1, 右侧将刚刚配置好的Service1Behavior与之进行关联, 这样整个服务端的配置就完成了.
保存以后, 完成的app.config如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration> <system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="NewBinding0">
<security>
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WcfServiceLibrary3.Service1Behavior"
name="WcfServiceLibrary3.Service1">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0"
contract="WcfServiceLibrary3.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary3/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceLibrary3.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="MyTestCert" storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WcfServiceLibrary3.Validator,WcfServiceLibrary3" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel> </configuration>
9. 创建证书并导入.
在开始菜单—>Microsoft Visual Studio2010—>Visual Studio Tools下面, 点击Visual Studio Command Prompt, 打开命令行窗口, 输入以下命令:
makecert -r -pe -n "CN=MyTestCert" -ss TrustedPeople -sr LocalMachine -sky exchange
10. 现在F5重新运行, 再次点击按钮1时, 抛出如下异常:
现在我们已经可以确定, 客户端再妄想匿名使用服务是不可能了, 接下来配置客户端的使用凭证.
接下来右击客户端的app.config, 继续选Edit WCF Configuration.
11, 创建endpoint behavior
在Advanced/endpoint behavior下面新建一个endpoint behavior:
然后点击Add, 新增一个clientCredential节点.
展开它的serviceCertificate节点, 选中defaultCertificate, 编辑它的属性如下图:
这几项的值和服务器端的设置是一致的.
12. 将此behavior绑定到endpoint
13. 指定dns
切换到identity标签, 将dns属性指定为我们的证书名:
至此, 客户端的配置也全部结束. 最终客户端的app.config代码为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="NewBehavior0">
<clientCredentials>
<serviceCertificate>
<defaultCertificate findValue="MyTestCert" storeLocation="LocalMachine"
storeName="TrustedPeople" x509FindType="FindBySubjectName" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message clientCredentialType="UserName" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary3/Service1/"
behaviorConfiguration="NewBehavior0" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1">
<identity>
<dns value="MyTestCert" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
14, 指定用户名和密码.
把客户端的按钮点击代码改为:
private void button1_Click(object sender, EventArgs e)
{
var ser = new ServiceReference1.Service1Client();
ser.ClientCredentials.UserName.UserName = "u";
ser.ClientCredentials.UserName.Password = "p";
MessageBox.Show(ser.GetData(0));
}
F5运行, 可以看到返回正确的结果, 而如果用户名和密码不正确, 则会抛出异常:
WCF身份验证二:基于消息安全模式的自定义身份验证的更多相关文章
- WCF身份验证一:消息安全模式之<Certificate>身份验证
消息安全模式的证书身份验证方式,基于WSHttpBinding绑定协议的实现过程.主要内容:基本概念,然后是制作证书.服务端配置.客户端配置.总结.这里应该和Transport传输安全模式之证书身份验 ...
- webservice安全性之 SoapHeader自定义身份验证
相信很多开发者都用过WebService来实现程序的面向服务,本文主要介绍WebService的身份识别实现方式,当然本文会提供一个不是很完善的例子,权当抱砖引玉了. 首先我们来介绍webservic ...
- Java自定义数据验证注解Annotation
本文转载自:https://www.jianshu.com/p/616924cd07e6 Java注解Annotation用起来很方便,也越来越流行,由于其简单.简练且易于使用等特点,很多开发工具都提 ...
- WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化
原文:WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制 ...
- Android消息推送(二)--基于MQTT协议实现的推送功能
国内的Android设备,不能稳定的使用Google GCM(Google Cloud Messageing)消息推送服务. 1. 国内的Android设备,基本上从操作系统底层开始就去掉了Googl ...
- ASP.NET Identity 身份验证和基于角色的授权
ASP.NET Identity 身份验证和基于角色的授权 阅读目录 探索身份验证与授权 使用ASP.NET Identity 身份验证 使用角色进行授权 初始化数据,Seeding 数据库 小结 在 ...
- Forms身份验证和基于Role的权限验证
Forms身份验证和基于Role的权限验证 从Membership到SimpleMembership再到ASP.NET Identity,ASP.NET每一次更换身份验证的组件,都让我更失望.Memb ...
- ASP.NET:Forms身份验证和基于Role的权限验证
从Membership到SimpleMembership再到ASP.NET Identity,ASP.NET每一次更换身份验证的组件,都让我更失望.Membership的唯一作用就是你可以参考它的实现 ...
- SmartMS如何使用二次验证码/虚拟MFA/两步验证/谷歌身份验证器?
一般点账户名——设置——安全设置中开通虚拟MFA两步验证 具体步骤见链接 SmartMS如何使用二次验证码/虚拟MFA/两步验证/谷歌身份验证器? 二次验证码小程序于谷歌身份验证器APP的优势 1.无 ...
随机推荐
- 【PTA 天梯赛】L2-016. 愿天下有情人都是失散多年的兄妹(深搜)
呵呵.大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人.父母.祖父母.曾祖父母.高祖父母)则不可通婚.本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚? 输入格式: 输入 ...
- js根据年份获取某月份有几天
function getNum(year, month) { var temp; month = parseInt(month, 10); temp = new Date(year, month, 0 ...
- 理解HBase
1.HBase HBase: Hadoop Database,根据Google的Big Table设计 HBase是一个分布式.面向列族的开源数据库.HDFS为Hbase提供了底层的数据存储服务,Ma ...
- 使用SQLite删除Mac OS X 中launchpad里的快捷方式
一般情况下,从App Store安装的应用程序,如果应用删除,那么launchpad里对应的图标会一起删除了. 而对于不是通过App Store安装的应用程序,删除应用程序,Launchpad中很可能 ...
- ctf题目writeup(7)
2019.2.10 过年休息归来,继续做题. bugku的web题,地址:https://ctf.bugku.com/challenges 1. http://123.206.87.240:8002/ ...
- go web cookie和session
cookie是存储在浏览器端,session是服务器端 cookie是有时间限制的,分会话cookie和持久cookie,如果不设置时间,那周期就是创建到浏览器关闭为止.这种是会话cookie,一般保 ...
- 学习RUNOOB.COM进度二
MongoDB 概念解析 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table collection 数据库表/集合 row document ...
- Sql Server 游标概念与实例
引言 先不讲游标的什么概念,看如下Sql Server2008 图例: 需求:两张表的O_ID是一一对应的,现在求将加薪的工资+原来的工资=现在的工资,也就是O_Salary=O_Salary+A_S ...
- 使用sqoop将mysql中表导入hive中报错
[hdfs@node1 root]$ sqoop import --connect jdbc:mysql://node2:3306/cm?charset-utf8 --username root -- ...
- VINS紧耦合优化公式及代码解析
1.首先确定待优化的状态变量 对应代码,优化参数为: Vector3d Ps[(WINDOW_SIZE + )];(平移向量) Vector3d Vs[(WINDOW_SIZE + )];(速度) M ...