WCF SSL(应用篇-Message)-02


1.Host 配置信息Message 安全模式配置
 <bindings>
      <wsHttpBinding>
        <binding  name="MessageAndUserName"   >
          <!--安全模式 为 Message  -->
          <security  mode="Message">
            <transport clientCredentialType="None"/>
            <!--客户端自定义验证 -->
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

行为

 <behaviors>
      <!--服务行为 运行于服务级别,适用于所有端点,负责内容如:实例化、事务、授权、审计 等-->
      <serviceBehaviors>
        <behavior name="WCFService.WCFServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <!-- mmc 命令 文件->添加/删除管理单元->证书->计算机证书 My=个人 查找名称=kfsmqoo 本地计算机 -->
            <serviceCertificate storeName="My"  x509FindType="FindBySubjectName" findValue="kfsmqoo" storeLocation="LocalMachine"/>
            <clientCertificate >
              <authentication certificateValidationMode="None" />
            </clientCertificate>
            <!--WCFServiceCert.CustomUserNamePasswordValidator 验证类 WCFServiceCert 命名空间 -->
            <userNameAuthentication userNamePasswordValidationMode="Custom"    customUserNamePasswordValidatorType="WCFServiceCert.CustomUserNamePasswordValidator,WCFServiceCert" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

以下是控制台跟xml的相关信息。如果不清楚证书如何生成,请参照 WCF SSL(证书篇)

Host 下面整个 App.config

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <!--服务行为 运行于服务级别,适用于所有端点,负责内容如:实例化、事务、授权、审计 等-->
      <serviceBehaviors>
        <behavior name="WCFService.WCFServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <!-- mmc 命令 文件->添加/删除管理单元->证书->计算机证书 My=个人 查找名称=kfsmqoo 本地计算机 -->
            <serviceCertificate storeName="My"  x509FindType="FindBySubjectName" findValue="kfsmqoo" storeLocation="LocalMachine"/>
            <clientCertificate >
              <authentication certificateValidationMode="None" />
            </clientCertificate>
            <!--WCFServiceCert.CustomUserNamePasswordValidator 验证类 WCFServiceCert 命名空间 -->
            <userNameAuthentication userNamePasswordValidationMode="Custom"    customUserNamePasswordValidatorType="WCFServiceCert.CustomUserNamePasswordValidator,WCFServiceCert" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <wsHttpBinding>
        <binding  name="MessageAndUserName"   >
          <!--安全模式 为 Message  -->
          <security  mode="Message">
            <transport clientCredentialType="None"/>
            <!--客户端自定义验证 -->
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <services>
      <service behaviorConfiguration="WCFService.WCFServiceBehavior" name="WCFServiceCert.CertService">
        <endpoint address="WCFService" binding="wsHttpBinding"  bindingConfiguration="MessageAndUserName" contract="WCFServiceCert.ICertService">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8001/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false"/>
  </system.serviceModel>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

2.ServiceContract 信息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;

namespace WCFServiceCert
{
    public class CertService : ICertService
    {
        public string GetData()
        {
            if (CustomUserNamePasswordValidator.flg_Checked == true)
            {
                return "验证通过";
            }
            else
            {
                return "验证失败";
            }
        }
    }

    [ServiceContract]
    public interface ICertService
    {
        [OperationContract(Name = "GetDataJson")]
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetData", BodyStyle = WebMessageBodyStyle.Bare)]
        string GetData();
    }
}

2.1 我们需要继承UserNamePasswordValidator 类,服务端Message模式需要引用 DLL

DLL 如下:

System.IdentityModel.dll

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

// <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFServiceCert.CustomUserNamePasswordValidator,WCFServiceCert" />
namespace WCFServiceCert
{
    public class CustomUserNamePasswordValidator : UserNamePasswordValidator
    {
        public static bool flg_Checked
        {
            get;
            set;
        }
        public override void Validate(string userName, string password)
        {
            if (userName == "kfsmqoo" && password == "123456")
            {
                flg_Checked = true;
                Console.WriteLine("验证成功!");
            }
            else
            {
                flg_Checked = false;
                Console.WriteLine("验证失败!");
            }
        }
    }
}

3 Client 端代码

3.1 Client端的引用

3.2 Client 端生成的app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_ICertService" 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">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" negotiateServiceCredential="true"
                            algorithmSuite="Default" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8001/WCFService" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ICertService" contract="Wcf_CustomService.ICertService"
                name="WSHttpBinding_ICertService">
                <identity>
                  <!--客户端验证服务器的证书的编码表示形式 Base64-->
                    <certificate encodedValue="AwAAAAEAAAAUAAAAvETLK3VQgp807ib52Hz0oQnQ0a4gAAAAAQAAAOwBAAAwggHoMIIBVaADAgECAhABEysIfmRhrUSM1FZxeuI5MAkGBSsOAwIdBQAwEjEQMA4GA1UEAxMHa2ZzbXFvbzAeFw0xNDA2MjMwMDI3MzJaFw0zOTEyMzEyMzU5NTlaMBIxEDAOBgNVBAMTB2tmc21xb28wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMX8IcsAvfSEoWcsl9b5QkEal5lk4Ml9uhFAxUApTScSwwhawyo02uNn7vw+Om6vZuupif+mzmhqZTf6t1R1s40x64gT4QjylRPFC212ZP7nQqekdUTWIIoVetb0tpkz0Anzvfe1DjDseTlTpryC6suk6/4pFPqYmUoLPFoa3eeNAgMBAAGjRzBFMEMGA1UdAQQ8MDqAEHEoWyOCGoKd77RjPKjbIjGhFDASMRAwDgYDVQQDEwdrZnNtcW9vghABEysIfmRhrUSM1FZxeuI5MAkGBSsOAwIdBQADgYEAK0tVy8ONNoQxWCFQolRAYbAZf0naY6aiyTnBEsf4aHgifK1J3A98TXoZZJV4qsEvmoBF9pEUa2KwGdit8hL3rDp/Z5JLzsabbBEc+IkK3N5VMzUTJwHCQl1P5mQX8+RdYL3xLkKqq9s6vGBi1t2v8BNzUZK41tjtJaXhlNckGbU=" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

3.3 客户端代码 和服务器的返回结果。

Wcf_CustomService.CertServiceClient client = new Wcf_CustomService.CertServiceClient();
client.ClientCredentials.UserName.UserName = "abc";
client.ClientCredentials.UserName.Password = "123456";
MessageBox.Show(client.GetDataJson());

Wcf_CustomService.CertServiceClient client1 = new Wcf_CustomService.CertServiceClient();
client1.ClientCredentials.UserName.UserName = "kfsmqoo";
client1.ClientCredentials.UserName.Password = "123456";
MessageBox.Show(client1.GetDataJson());

看看服务器的返回信息。

WCF SSL(应用篇-Message)-02

时间: 2024-10-10 12:30:19

WCF SSL(应用篇-Message)-02的相关文章

[老老实实学WCF] 第三篇 在IIS中寄存服务

原文:[老老实实学WCF] 第三篇 在IIS中寄存服务 老老实实学WCF 第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我们对WCF的编程生命周期有了一个最基本的了解. 在前两篇中演示的例子,一定要力求背着做下来,包括源程序.配置文件都要背着一行行的手写下来,这样才能有深刻的体会.WCF的知识零散复杂,必须扎扎实实的学习和练习.如果你还没有做到了然于胸,现在赶紧翻

[老老实实学WCF] 第五篇 再探通信--ClientBase

原文:[老老实实学WCF] 第五篇 再探通信--ClientBase 老老实实学WCF 第五篇 再探通信--ClientBase 在上一篇中,我们抛开了服务引用和元数据交换,在客户端中手动添加了元数据代码,并利用通道工厂ChannelFactory<>类创建了通道,实现了和服务端的通信.然而,与服务端通信的编程模型不只一种,今天我们来学习利用另外一个服务类ClientBase<>来完成同样的工作,了解了这个类的使用方法,我们对服务引用中的关键部分就能够理解了. ClientBase

[老老实实学WCF] 第六篇 元数据交换

原文:[老老实实学WCF] 第六篇 元数据交换 老老实实学WCF 第六篇 元数据交换 通过前两篇的学习,我们了解了WCF通信的一些基本原理,我们知道,WCF服务端和客户端通过共享元数据(包括服务协定.服务器终结点信息)在两个终结点上建立通道从而进行通信.我们通过手写代码(或配置)的方式为服务端编写了元数据信息,没有借助元数据交换就实现了通信.然而在实际应用中,元数据往往是很多的,而且重复编写元数据的工作也是不值得的,因此必然会用到元数据交换的方式让客户端获取元数据,本篇我们就来进一步了解一下元数

[老老实实学WCF] 第四篇 初探通信--ChannelFactory

原文:[老老实实学WCF] 第四篇 初探通信--ChannelFactory 老老实实学WCF 第四篇 初探通信--ChannelFactory 通过前几篇的学习,我们简单了解了WCF的服务端-客户端模型,可以建立一个简单的WCF通信程序,并且可以把我们的服务寄宿在IIS中了.我们不禁感叹WCF模型的简单,寥寥数行代码和配置,就可以把通信建立起来.然而,仔细品味一下,这里面仍有许多疑点:服务器是如何建起服务的?我们在客户端调用一个操作后发生了什么?元数据到底是什么东西?等等.我们现在对WCF的理

[老老实实学WCF] 第八篇 实例化

老老实实学WCF 第八篇 实例化 通过上一篇的学习,我们简单地了解了会话,我们知道服务端和客户端之间可以建立会话连接,也可以建立非会话连接,通信的绑定和服务协定的ServiceContract 的SessionMode属性共同决定了连接是否是会话的.会话连接在会话保持阶段服务端可以记住客户端,而非会话连接则不会,相同客户端的多次调用会被认为是不同的客户端发起的. 会话这个特性是许多其他特性的基础,例如我们今天要学习的实例化.连接是否是会话对实例化的过程将产生不同的影响.今天我们就来研究这个问题.

老老实实学WCF[第三篇] 在IIS中寄宿服务

老老实实学WCF 第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我们对WCF的编程生命周期有了一个最基本的了解. 在前两篇中演示的例子,一定要力求背着做下来,包括源程序.配置文件都要背着一行行的手写下来,这样才能有深刻的体会.WCF的知识零散复杂,必须扎扎实实的学习和练习.如果你还没有做到了然于胸,现在赶紧翻回去把例子再做一遍. 今天让我们稍微深入一点,了解一些关

老老实实学WCF[ 第七篇] 回话

老老实实学WCF 第七篇 会话 通过前几篇的学习,我们已经掌握了WCF的最基本的编程模型,我们已经可以写出完整的通信了.从这篇开始我们要深入地了解这个模型的高级特性,这些特性用来保证我们的程序运行的高效.稳定和安全. 首先我们来学习会话. 1. 什么是会话 会话是通信双方进行通信的一个时间片.一个语境或者说一个上下文,在这个特定的环境中,通信的双方是彼此认识的,就像两个人在聊天,他们都很清楚谁在聆听自己讲话,也很清楚对方讲的话是给自己听的,简单的说就是通信双方是可以记住彼此的. 一旦会话结束了,

(转)[老老实实学WCF] 第四篇 初探通信--ChannelFactory

第四篇 初探通信--ChannelFactory 通过前几篇的学习,我们简单了解了WCF的服务端-客户端模型,可以建立一个简单的WCF通信程序,并且可以把我们的服务寄宿在IIS中了.我们不禁感叹WCF模型的简单,寥寥数行代码和配置,就可以把通信建立起来.然而,仔细品味一下,这里面仍有许多疑点:服务器是如何建起服务的?我们在客户端调用一个操作后发生了什么?元数据到底是什么东西?等等.我们现在对WCF的理解应该还处于初级阶段,我们就会觉得有许多这样的谜团了. 虽然我们生活在WCF为我们构建的美好的应

iOS开发Swift篇(02) NSThread线程相关简单说明

iOS开发Swift篇(02) NSThread线程相关简单说明 一 说明 1)关于多线程部分的理论知识和OC实现,在之前的博文中已经写明,所以这里不再说明. 2)该文仅仅简单讲解NSThread在swift语境中的一些使用和注意点,别他. 3)本文涉及代码可以从https://github.com/HanGangAndHanMeimei/Code地址获得. 二 NSThread的基本使用和创建 1)基本用法(主线程|当前线程) 1 //1.获得执行该方法的当前线程 2 let currentT