上一篇文章中介绍了如何使用basicHttpBinding构建UserName授权的WCF应用程序,本文将为您介绍如何使用wsHttpBinding构建非SSL的UserName安全授权的WCF应用程序。

  与上篇文章一样,同样将该示例分为服务端与客户端介绍。

  1. 服务端

  (1) 实现CustomUserNameValidator

  与上篇文章一样,需要首先实现CustomUserNameValidator,如果还不知道如何生成CustomUserNameValidator,请参考上一篇文章

 public class CustomUserNameValidator : UserNamePasswordValidator
{
private const string USERNAME_ELEMENT_NAME = "userName"; private const string PASSWORD_ELEMENT_NAME = "password"; private const string FAULT_EXCEPTION_MESSAGE = "UserName or Password is incorrect!"; public override void Validate(string userName, string password)
{
Guarder.Guard.ArgumentNotNull(userName)
.ArgumentNotNull(password);
var validateUserName = ConfigurationManager.AppSettings[USERNAME_ELEMENT_NAME];
var validatePassword = ConfigurationManager.AppSettings[PASSWORD_ELEMENT_NAME];
var validateCondition = userName.Equals(validateUserName) && password.Equals(validatePassword);
if (!validateCondition)
{
throw new FaultException(FAULT_EXCEPTION_MESSAGE);
}
}
}

  (2) 注册服务端证书

  这个环节是在上一篇文章中没有的,后文中要介绍到,我们使用了Message的方式加密消息内容,因此,我们需要将传输内容加密,因此需要使用证书进行加密。我们使用微软自带的"makecert.exe"命令行工具向currentUser注册一个证书。使用Visual Studio自带的命令行工具执行下面命令行。

 makecert.exe -sr CurrentUser -ss My -a sha1 -n CN=ServerCert -sky exchange –pe

  (3) 完成服务端配置文件

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="username" value="username"/>
<add key="password" value="password"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="securityBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate
findValue="ServerCert"
x509FindType="FindBySubjectName"
storeLocation="CurrentUser"
storeName="My"/>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="TimeSynchronizeServer.CustomUserNameValidator,TimeSynchronizeServer"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="securityMessageBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="TimeSynchronizeServer.TimeSynchronizeService"
behaviorConfiguration="securityBehavior">
<endpoint address="http://127.0.0.1/12216/TimeSynchronize"
binding="wsHttpBinding" bindingConfiguration="securityMessageBinding"
contract="TimeSynchronizeServer.ITimeSynchronizeService">
<identity>
<dns value="ServerCert" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/TimeSynchronizeServer/TimeSynchronizeService/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>

  其中serviceCredentials节点中添加了serviceCertificate节点,该节点用来指定使用的证书。findValue,此attribute指定的是(2)中命令行中CN=右侧的字符。userNameAuthentication制定了自定义的Validator。binding节点中使用了wsHttpBinding,并将传输的加密方式指定为Message,并制定UserName为授权方式。

  2. 客户端

  (1) 完成客户端配置文件

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="userName" value="username"/>
<add key="password" value="password"/>
</appSettings>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="securityMessageBidning">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://127.0.0.1/12216/TimeSynchronize/"
binding="wsHttpBinding" bindingConfiguration="securityMessageBidning"
contract="ITimeSynchronizeService" name="DefaultBinding_ITimeSynchronizeService_ITimeSynchronizeService">
<identity>
<dns value="ServerCert"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

  需要注意的是,binding节点需要与服务端配置文件中的binding配置相同。特别要注意的是,endpoint节点中的identity节点中的dns的value需要与证书名称相同,否则会抛出一个异常,具体问题我还没搞明白,不过搜索了一下,发现这样能够解决问题。

  (2) 完成客户端调用代码

 private const string USERNAME = "userName";
private const string PASSWORD = "password"; static void Main ( string[] args )
{
var proxy = new TimeSynchronizeServiceClient ( );
var userName = ConfigurationManager.AppSettings[USERNAME];
var password = ConfigurationManager.AppSettings[PASSWORD];
proxy.ClientCredentials.UserName.UserName = userName;
proxy.ClientCredentials.UserName.Password = password;
proxy.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.None;
var time = proxy.GetTime ( );
var builder = new StringBuilder ( );
builder.Append ( "Server time is:" ).Append ( " " ).Append ( time );
var message = builder.ToString ( );
Console.WriteLine ( message );
18   Console.ReadKey ( );
}

OK,大功告成!

下一篇:[WCF安全3]使用wsHttpBinding构建基于SSL与UserName授权的WCF应用程序

[WCF安全2]使用wsHttpBinding构建UserName授权的WCF应用程序,非SSL的更多相关文章

  1. [WCF安全1]使用basicHttpBinding构建UserName授权的WCF应用程序

    最近到了新公司,leader让我研究一下WCF的传输安全机制.以前也做过WCF的应用,但是很少涉及安全方面的东西.所以,花了三天的时间研究了一下如何在WCF的应用程序中配置安全.在这个系列文章中,我会 ...

  2. [WCF安全3]使用wsHttpBinding构建基于SSL与UserName授权的WCF应用程序

    上一篇文章中介绍了如何使用wsHttpBinding构建UserName授权的WCF应用程序,本文将为您介绍如何使用wsHttpBinding构建基于SSL的UserName安全授权的WCF应用程序. ...

  3. 构建RESTful风格的WCF服务

    构建RESTful风格的WCF服务 RESTful Wcf是一种基于Http协议的服务架构风格. 相较 WCF.WebService 使用 SOAP.WSDL.WS-* 而言,几乎所有的语言和网络平台 ...

  4. WCF开发实战系列一:创建第一个WCF服务

    WCF开发实战系列一:创建第一个WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在这个实战中我们将使用DataContract,ServiceContract ...

  5. WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]

    原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇] 通过<实现篇>对WSDL元素和终结点三要素的之间的匹配关系的介绍,我们知道了WSDL的Binding ...

  6. WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]

    原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...

  7. WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]

    原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...

  8. 利用ant脚本 自动构建svn增量/全量 系统程序升级包【转】

    引文:我们公司是做自己使用产品,迭代更新周期短,每次都花费较多时间和精力打包做增量更新,发现了一篇文章用于 自动构建svn增量/全量 系统程序升级包,收藏之,希望可以通过学习,更加简化我们的工作. 文 ...

  9. 教你轻松构建基于 Serverless 架构的小程序

    前言 自 2017 年第一批小程序上线以来,越来越多的移动端应用以小程序的形式呈现.小程序触手可及.用完即走的优点,大大降低了用户的使用负担,也使小程序得到了广泛的传播.在阿里巴巴,小程序也被广泛地应 ...

随机推荐

  1. android异常:Can not perform this action after onSaveInstanc

    extends:http://zhiweiofli.iteye.com/blog/1539467 本人某个android项目开发阶段一直运行良好,直到上线前夕,在某款跑着android 4.03系统的 ...

  2. Swift - 实现tableView单选系统样式

    // 实现tableView单选 import UIKit class ViewController: UIViewController { var tableView: UITableView! o ...

  3. goole进不去?

    1.把hosts文件放到C:\Windows\System32\drivers\etc目录下就可以上了.hosts文件自己下载 2. 上vpn ,注册个账号,每个账号500M的FQ流量也可以

  4. 封装自己的getClass

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. mongodb实现对某列求和SUM

    mongodb数据如下: db.cpc_0103.find() { "a" : 8, "b" : "108177_200701010000" ...

  6. 170509、文本编辑器编写的shell脚本在linux下无法执行的解决方法

    今天碰到一个奇怪的问题,编写好的shell脚本再linux上执行一直提示找不到文件或目录,后来想想是文本编辑器的问题,记录下来!!! 1.查看当前文本格式 Notepad++界面中,在右下角有文件格式 ...

  7. HI3518E用J-link烧写裸板fastboot u-boot流程

    Hi3518E的裸板烧写fastboot是不能像HI3531那样,可以通过FB直接烧写.遵循ARM9的烧写流程.其中一般u-boot的烧写流程可分为几类:第一:通过编程器芯片直接烧写:第二通过RVDS ...

  8. 设计模式之——Composite模式

    composite模式又叫做组合模式/复合模式. 它是一种能够使容器与内容具有一致性,创造出递归结构的模式. 示例程序是列出文件夹以及其内部文件与文件夹一览的功能: 可以由示例图看出,有一个电影文件夹 ...

  9. python三层架构

    conf/setting(配置文件)    一般是对utility进行相关设置   index(主文件) main函数触发某个对象的业务逻辑方法   model(数据库) admin  是对数据库的操 ...

  10. git-【二】本地git操作提交、版本回退

    一.创建版本库,提交文件 什么是版本库?版本库又名仓库,英文名repository,你可以简单的理解一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改,删除,Git都能跟踪,以便任 ...