上一篇文章中介绍了如何使用wsHttpBinding构建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) 注册服务端证书

  与上篇文章中一样,首先需要向currentUser或localMachine中注册一个X509证书。

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

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

 <?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>
<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="TimeSynchronizeHttpsServer.CustomUserNameValidator,TimeSynchronizeHttpsServer"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="securityMessageBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="TimeSynchronizeHttpsServer.TimeSynchronizeService" behaviorConfiguration="securityBehavior">
<endpoint address="https://127.0.0.1:12218/TimeSynchronize"
binding="wsHttpBinding" bindingConfiguration="securityMessageBinding"
contract="TimeSynchronizeHttpsServer.ITimeSynchronizeService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/TimeSynchonizeHttpsServer/TimeSynchronizeService/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>

  其中serviceCredentials节点中添加了serviceCertificate节点,该节点用来指定使用的证书。findValue,此attribute指定的是(2)中命令行中CN=右侧的字符。userNameAuthentication制定了自定义的Validator。binding节点中使用了wsHttpBinding,并将传输的加密方式指定为TransportWithMessageCredential,并制定Message的授权方式为UserName,Transport的授权方式为Basic。endpoint的地址需要使用https协议作为基地址的头部。

  (4) 将服务端应用程序绑定到SSL证书上

  如果你的WCF的承载方式为self-host(所谓self-host方式,指将WCF服务host在一个windows外壳中,包括winform、wpf、windowService。这种方式是相对于IIS承载来说的,IIS承载方式网上介绍的例子已经很多了,这篇文章主要介绍self-host方式。),需要手动将你的外壳程序绑定到SSL证书上。

  首先需要使用(2)中的方式在LocalMachine中建立一个证书,注意,一定是LocalMachine中。然后,使用下面的命令行代码,将你的服务端外壳程序绑定到SSL证书上。

 netsh http add sslcert ipport=0.0.0.0:12218 certhash=1dca86867481b22c8f15a134df62af649cc3343a clientcertnegotiation=enable appid={02639d71-0935-35e8-9d1b-9dd1a2a34627}

  其中,ipport的值中的0.0.0.0代表本地地址,冒号后面代表端口;certhash的值为证书的thumbPrint值,怎么找到这个值呢?follow this article吧,哈哈,英文的,z正好提高一下你的英语水平,哈哈。appid中的值是程序的guid,在项目属性的assemblyInfo中可以找到。

  2. 客户端

  (1) 实现CertificateValidator

  这个是在第二篇文章中没有的,这个Validator干啥用的呢。这个东西是因为我们的证书都是自己颁发给给自己的,所以在安全性上存在一些问题,如果我们用根证书颁发机构颁发的证书,让这个Validator见鬼去吧,哈哈。

 class CertificateValidator
{
  public static void SetCertificatePolicy ( )
  {
    ServicePointManager.ServerCertificateValidationCallback
+= RemoteCertificateValidate;
  }
  private static bool RemoteCertificateValidate ( object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error )
  {
    System.Console.WriteLine ( "Warning, trust any certificate" );
  return true;
  }
}

  在客户端调用代码时,调用客户端的Contract之前,调用CertificateValidator.SetCertificatePolicy()方法。

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

 <?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="securityMixedBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://127.0.0.1:12218/TimeSynchronize"
binding="wsHttpBinding" bindingConfiguration="securityMixedBinding"
contract="ITimeSynchronizeService"
name="DefaultBinding_ITimeSynchronizeService_ITimeSynchronizeService" />
</client>
</system.serviceModel>
</configuration>

  需要注意的是,binding节点需要与服务端配置文件中的binding配置相同。endpoint的地址与service相同,都要采用https基地址。

  (3) 实现客户端调用代码

 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;
CertificateValidator.SetCertificatePolicy ( );
var time = proxy.GetTime ( );
var builder = new StringBuilder ( );
builder.Append ( "Server time is:" ).Append ( " " ).Append ( time );
var message = builder.ToString ( );
Console.WriteLine ( message );
Console.ReadKey ( );
}

  在调用客户端的Contract之前,需要调用CertificateValidator.SetCertificatePolicy()方法。

  OK,打完收工。

[WCF安全3]使用wsHttpBinding构建基于SSL与UserName授权的WCF应用程序的更多相关文章

  1. 使用wsHttpBinding构建Message安全模式和UserName授权

    http://www.cnblogs.com/artech/archive/2011/05/22/authentication_01.html https://www.cnblogs.com/Fran ...

  2. [WCF安全2]使用wsHttpBinding构建UserName授权的WCF应用程序,非SSL

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

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

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

  4. 基于SSL实现Mysql加密主从

    Mysql主从复制是明文传输的,对于一些特殊的场合是绝对不允许的,数据的安全性会受到威胁,在这里,简单的构建基于SSL的mysql主从复制 Ps:这里采用master-mysql为CA服务器 主端生成 ...

  5. 基于SSL实现MySQL的加密主从复制

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012974916/article/details/53316758 大家都知道MySQL的主从复制 ...

  6. 重温WCF之WCF传输安全(十三)(2)基于SSL的WCF匿名客户端(转)

    转载地址:http://www.cnblogs.com/lxblog/archive/2012/09/13/2683514.html 这一篇我们利用上一篇制作的证书,来演示一个基于SSL的WCF服务, ...

  7. 重温WCF之WCF传输安全(十三)(4)基于SSL的WCF对客户端采用证书验证(转)

    转载地址:http://www.cnblogs.com/lxblog/archive/2012/09/20/2695397.html 前一篇我们演示了基于SSL的WCF 对客户端进行用户名和密码方式的 ...

  8. 构建基于WCF Restful Service的服务

    前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添加服务端引用才能使用(虽然看到网络上已经提供了这方面的Dynamic Proxy,但是没有这种方式简便), ...

  9. [转]构建基于WCF Restful Service的服务

    本文转自:http://www.cnblogs.com/scy251147/p/3566638.html 前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添 ...

随机推荐

  1. D. Mike and Feet---cf548D(最值)

    题目链接:http://codeforces.com/problemset/problem/548/D 给你n个数,对于(1,n)长度,让你找到线段的最小值的最大值是多少 #include<io ...

  2. 【使用时发生的意外】HDFS 分布式写入问题 AlreadyBeingCreatedException

    进行追加文件时出现AlreadyBeingCreatedException错误 堆栈信息大致如下: org.apache.hadoop.ipc.RemoteException(org.apache.h ...

  3. 网络爬虫值scrapy框架基础

    简介 Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv.json等文件中. 首先我们安装Scrapy. 其可以应用在数据挖掘,信息处理或存储历史 ...

  4. 再次学习javascript中的參数传递

     javascript中的全部函数的參数传递都是依照值传递的,做了以下測试:    function addTen(num){ num +=10; return num; } var count = ...

  5. 以EJB谈J2EE规范

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/xiaoduishenghuogo/article/details/24800703 接触J2EE的时 ...

  6. java-mybaits-00401-Mapper-输入输出

    Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心. 1.parameterType(输入类型) 1.1.#{}与${} #{} ...

  7. 模块讲解----json模块(跨平台的序列化与反序列化)

    一.json的特点 1.只能处理简单的可序列化的对象:(字典,列表,元祖) 2.json支持不同语言之间的数据交互:(python  -  go,python - java)   二.使用场景 1.玩 ...

  8. sublime2常用设置

    设置文本字体格式 • Preferences -> Setting-User • 加入设置:"font_face" : "courier new", &q ...

  9. iOS App 上架(Analysis 工具使用)

    随着iOS开发的流行,针对iOS开发涉及的方方面面,早有一些公司提供了专门的解决方案或工具.这些解决方案或工具包括:用户行为统计工具(友盟,Flurry,Google Analytics等), App ...

  10. HDU 1142 A Walk Through the Forest(Dijkstra+记忆化搜索)

    题意:看样子很多人都把这题目看错了,以为是求最短路的条数.真正的意思是:假设 A和B 是相连的,当前在 A 处, 如果 A 到终点的最短距离大于 B 到终点的最短距离,则可以从 A 通往 B 处,问满 ...