惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
T
Threat Research - Cisco Blogs
H
Hacker News: Front Page
N
News and Events Feed by Topic
Know Your Adversary
Know Your Adversary
Cisco Talos Blog
Cisco Talos Blog
SecWiki News
SecWiki News
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tor Project blog
K
Kaspersky official blog
Forbes - Security
Forbes - Security
Webroot Blog
Webroot Blog
Schneier on Security
Schneier on Security
P
Privacy & Cybersecurity Law Blog
H
Heimdal Security Blog
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
V
Vulnerabilities – Threatpost
T
Tenable Blog
T
Tailwind CSS Blog
P
Privacy International News Feed
WordPress大学
WordPress大学
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
博客园 - Franky
Hacker News: Ask HN
Hacker News: Ask HN
Jina AI
Jina AI
C
Cybersecurity and Infrastructure Security Agency CISA
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
雷峰网
雷峰网
Vercel News
Vercel News
A
About on SuperTechFans
爱范儿
爱范儿
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog
The Last Watchdog
The Last Watchdog
Engineering at Meta
Engineering at Meta
Spread Privacy
Spread Privacy
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园 - 司徒正美
量子位
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recorded Future
Recorded Future
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Martin Fowler
Martin Fowler
Project Zero
Project Zero

博客园 - chnking

Biztalk AS2开发经验总结 BizTalk发布WS-Security的web services BizTalk调用WS-Security的web services BizTalk中利用ESSO保存外部系统用户凭据 biztalk大规模高性能高可用部署方案 Biztalk 2009在Windows 2008 R2环境中的High Availability(Cluster群集)部署(下)--AA模式 Biztalk 2009在Windows 2008 R2环境中的High Availability(Cluster群集)部署(上)--AP模式 biztalk中使用biztalk adapter Pack适配器之一 – WCF-SQL WCF系列_分布式事务(下) WCF系列_分布式事务(上) Biztalk中Host Instance线程控制 biztalk在用户代码中构造多部分消息 使用biztalk API新建Receive Location 主流SOA厂商和相关产品 WCF系列(九) - WCF安全系列(四) - WSHttpBinding绑定之Transport安全模式 WCF系列(七) - WCF安全系列(二) - netTCPBinding绑定之Transport安全模式 WCF系列(六) - WCF安全系列(一) - basicHttpBinding 深入biztalk的Sequential Convoys保护 IIS客户端证书访问配置
WCF系列(八) - WCF安全系列(三) - netTCPBinding绑定之Message安全模式
chnking · 2008-10-15 · via 博客园 - chnking

一、         netTCPBinding

3           安全模式 – Message

3.1.         客户端验证 – None

3.1.1.     获得和安装证书

3.1.2.     服务端代码

3.1.3.     客户端代码

3.1.4.     测试

3.2.         客户端验证 – Windows

3.2.1.     获得和安装证书

3.2.2.     服务端代码

3.2.3.     客户端代码

3.2.4.     测试

3.3.         客户端验证 – UserName

3.3.1.     获得和安装证书

3.3.2.     服务端代码

3.3.3.     客户端代码

3.3.4.     测试

3.3.5.     身份模拟和访问权限控制

3.4.         客户端验证:Certificate

3.4.1.     获得和安装证书

3.4.2.     服务端代码

3.4.3.     客户端代码

3.4.4.     测试

3.4.5.     证书映射到windows用户

一、  netTCPBinding

此绑定使用TCP传输协议,不具交互性,只适用于 WCF WCF 的通信。

此绑定的传输安全性的实现:

l  安全模式Message

这种模式WCF中都一样,都是使用WS-*通过对SOAP消息本身进行加密、签名等等的处理来保证安全性。Message模式不依赖于传输协议。服务端需要指定服务端证书,用来加密服务端和客户端相互传送的消息。

l  Transport – 客户端windows验证

使用windows security保证消息的安全,使用windows credential进行身份验证。

这种方式不需要服务端证书。

至于windows security的实现安全的原理我还不明白,这部分尚待了解。

l  Transport – 客户端其他验证方式

使用TLS over TCP实现传输安全性,需要服务端证书。

一般大家对SSL比较熟悉,对TLS可能要陌生些,其实可以说TLS协议可以看作跟SSL协议后续版本。1994年,netscape为了在internet上进行安全的数据传输,开发了的SSL协议,后来标准化组织把SSL标准化了,稍作修改改名叫TLS,在一般的使用意义上,这两个协议差别不大,就是在保证消息完整性的散列算法上使用了不同的算法。

TLS over TCP 直接建立在TCP协议上,通过传输层TCP协议实现安全性。

netTCPBinding绑定是直接使用TCP协议,不走HTTP,所以不能使用IIS宿主。这部分的测试实例采用自宿主的服务端console应用,基于代码的方式。

3、 安全模式 – Message

这部分测试netTCPBinding绑定的Message安全模式的各种情况。

共用测试WCF服务类

所有测试都是用同样的服务端contract和实现这个contractservice

[ServiceContract(Namespace = "http://chnking.com")]

public interface IGetIdentity

{

    [OperationContract]

    string Get(string ClientIdentity);

}

public class GetIdentity : IGetIdentity

{

    public string Get(string ClientIdentity)

    {

        return ("服务端Identity '" + ServiceSecurityContext.Current. PrimaryIdentity.Name +

            "'\n\r客户端Identity '" + ClientIdentity + "'");

    }

}

代码很简单,一个contract提供了一个Get方法,接收一个string参数,返回一个string参数。在后面的测试中,客户端把客户端安全上下文的Identity发送到服务端,服务端返回服务端安全上下文的Identity给客户端。

3.1.   客户端验证 – None

这部分的测试代码: NetTcpBinding_Message_None.rar

netTCPBinding绑定的Message安全模式,客户端None验证。此时将使用服务端证书,通过WS-Trust协议建立的安全通道,原理上类似SSLTLS的机制(但不是通过网络传输层来实现,而是通过处理SOAP中的消息)来保证消息的安全性。

这种方式的安全性:

完整性

使用服务端证书,通过WS-Trust协议建立的安全通道

保密性

使用服务端证书,通过WS-Trust协议建立的安全通道

服务端身份身份验证

服务端证书提供

客户端身份验证

没有

3.1.1.   获得和安装证书

这里用Makecert.exe工具生成证书,使用下面的命令:

makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe -r

这是服务端证书,win2008是服务端的机器名。

如果做过前面BasicHttpBinding的测试,这个服务端证书就应该已经有了。

3.1.2.   服务端代码

internal static ServiceHost myServiceHost = null;

internal static void Main()

{

    NetTcpBinding myBinding = new NetTcpBinding();

    myBinding.Security.Mode = SecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;

    Uri baseAddress = new Uri("net.tcp://localhost:8056/WCFService/");

    myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);

    ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint

        (typeof(IGetIdentity), myBinding, "GetIdentity");

    //设置服务端证书

    myServiceHost.Credentials.ServiceCertificate.SetCertificate("CN=win2008");

    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

    behavior.HttpGetEnabled = true;

    behavior.HttpGetUrl = new Uri("http://localhost:8057/mex");

    myServiceHost.Description.Behaviors.Add(behavior);

    myServiceHost.Open();

    Console.WriteLine("Service started!");

    Console.ReadLine();

    myServiceHost.Close();

}

3.1.3.   客户端代码

static void Main(string[] args)

{

    NetTcpBinding myBinding = new NetTcpBinding();

    myBinding.Security.Mode = SecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;

    EndpointAddress ea = new EndpointAddress("net.tcp://win2008:8056/WCFService/GetIdentity");

    GetIdentityClient gc = new GetIdentityClient(myBinding, ea);

    //不验证服务端证书的有效性

    gc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =

        System.ServiceModel.Security.X509CertificateValidationMode.None;

    //为使用TcpTrace跟踪消息设置的TcpTrace监听端口

    ClientViaBehavior myClientViaBehavior = new ClientViaBehavior

        (new Uri("net.tcp://win2008:8055/WCFService/GetIdentity"));

    gc.Endpoint.Behaviors.Add(myClientViaBehavior);

    //执行代理类Get方法

    string result = gc.Get(WindowsIdentity.GetCurrent().Name);

    Console.WriteLine(result);

    Console.ReadLine();

}

3.1.4.   测试

clip_image002

3.2.   客户端验证 – Windows

这部分的测试代码: NetTcpBinding_Message_Windows.rar

netTCPBinding绑定的Message安全模式,客户端Windows验证。此时将使用服务端证书,通过WS-Trust协议建立的安全通道,原理上类似SSLTLS的机制(但不是通过网络传输层来实现,而是通过处理SOAP中的消息)来保证消息的安全性。

这种方式的安全性:

完整性

使用服务端证书,通过WS-Trust协议建立的安全通道

保密性

使用服务端证书,通过WS-Trust协议建立的安全通道

服务端身份身份验证

服务端证书提供

客户端身份验证

Windows身份验证

3.2.1.   获得和安装证书

这里用Makecert.exe工具生成证书,使用下面的命令:

makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe -r

这是服务端证书,win2008是服务端的机器名。

如果做过前面BasicHttpBinding的测试,这个服务端证书就应该已经有了。

3.2.2.   服务端代码

internal static ServiceHost myServiceHost = null;

internal static void Main()

{

    NetTcpBinding myBinding = new NetTcpBinding();

    myBinding.Security.Mode = SecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

    Uri baseAddress = new Uri("net.tcp://localhost:8056/WCFService/");

    myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);

    ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint

        (typeof(IGetIdentity), myBinding, "GetIdentity");

    //设置服务端证书

    myServiceHost.Credentials.ServiceCertificate.SetCertificate("CN=win2008");

    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

    behavior.HttpGetEnabled = true;

    behavior.HttpGetUrl = new Uri("http://localhost:8057/mex");

    myServiceHost.Description.Behaviors.Add(behavior);

    myServiceHost.Open();

    Console.WriteLine("Service started!");

    Console.ReadLine();

    myServiceHost.Close();

}

3.2.3.   客户端代码

static void Main(string[] args)

{

    NetTcpBinding myBinding = new NetTcpBinding();

    myBinding.Security.Mode = SecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

    EndpointAddress ea = new EndpointAddress("net.tcp://win2008:8056/WCFService/GetIdentity");

    GetIdentityClient gc = new GetIdentityClient(myBinding, ea);

    //不验证服务端证书的有效性

    gc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =

        System.ServiceModel.Security.X509CertificateValidationMode.None;

    //为使用TcpTrace跟踪消息设置的TcpTrace监听端口

    ClientViaBehavior myClientViaBehavior = new ClientViaBehavior

        (new Uri("net.tcp://win2008:8055/WCFService/GetIdentity"));

    gc.Endpoint.Behaviors.Add(myClientViaBehavior);

    //执行代理类Get方法

    string result = gc.Get(WindowsIdentity.GetCurrent().Name);

    Console.WriteLine(result);

    Console.ReadLine();

}

3.2.4.   测试

clip_image004

可以看出,客户端windows身份被传送到服务端。

3.3.   客户端验证 – UserName

这部分的测试代码: NetTcpBinding_Message_UserName.rar

netTCPBinding绑定的Message安全模式,客户端使用UserName验证。此时将使用服务端证书,通过WS-Trust协议建立的安全通道,原理上类似SSLTLS的机制(但不是通过网络传输层来实现,而是通过处理SOAP中的消息)来保证消息的安全性。

这种方式的安全性:

完整性

使用服务端证书,通过WS-Trust协议建立的安全通道

保密性

使用服务端证书,通过WS-Trust协议建立的安全通道

服务端身份身份验证

服务端证书提供

客户端身份验证

客户端提供的用户名和密码

3.3.1.   获得和安装证书

这里用Makecert.exe工具生成证书,使用下面的命令:

makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe -r

这是服务端证书,win2008是服务端的机器名。

如果做过前面BasicHttpBinding的测试,这个服务端证书就应该已经有了。

3.3.2.   服务端代码

ContractServices部分的代码:

[ServiceContract(Namespace = "http://chnking.com")]

public interface IGetIdentity

{

    [OperationContract]

    string Get(string ClientIdentity);

}

public class GetIdentity : IGetIdentity

{

    [PrincipalPermission(SecurityAction.Demand, Role = "admin")]

    public string Get(string ClientIdentity)

    {

        IPrincipal myWindowsPrincipal = (IPrincipal)Thread.CurrentPrincipal;

        return ("Identity of server is'" + myWindowsPrincipal.Identity.Name +

            "'\n\rIdentity of client is '" + ClientIdentity + "'");

    }

}

这部分代码跟前面的测试例子一样,只是为了测试服务端模拟身份后的权限控制在Get方法前增加了了如下的控制访问的attribute

    [PrincipalPermission(SecurityAction.Demand, Role = "admin")]

表示只有运行方法的当前线程安全上下文的identity属于admin角色时才有权限访问这个方法。

服务宿主部分的代码:

internal class MyServiceHost

{

    internal static ServiceHost myServiceHost = null;

    internal static void Main()

    {

        NetTcpBinding myBinding = new NetTcpBinding();

        myBinding.Security.Mode = SecurityMode.Message;

        myBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

        Uri baseAddress = new Uri("net.tcp://localhost:8056/WCFService/");

        myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);

        ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint

            (typeof(IGetIdentity), myBinding, "GetIdentity");

        //设置服务端证书

        myServiceHost.Credentials.ServiceCertificate.SetCertificate("CN=win2008");

        //默认服务端PrincipalPermissionModeUseWindowsGroups,将Thread.CurrentPrincipal设置为WindowsPrincipal

        //一般是windows验证时映射到windows用户。

        //本例需要自己设置Thread.CurrentPrincipal,故此处设置为None

        myServiceHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.None;

        //设置客户端username在服务端验证模式为Custom

        myServiceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode =

            System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;

        myServiceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new customUserNamePasswordValidator();

        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

        behavior.HttpGetEnabled = true;

        behavior.HttpGetUrl = new Uri("http://localhost:8057/mex");

        myServiceHost.Description.Behaviors.Add(behavior);

        myServiceHost.Open();

        Console.WriteLine("Service started!");

        Console.ReadLine();

        myServiceHost.Close();

    }

}

public class customUserNamePasswordValidator : System.IdentityModel.Selectors.UserNamePasswordValidator

{

    public override void Validate(string username, string password)

    {

        if (username == "chnking" && password == "jjz666")

        {

            string[] roles = { "admin", "operator" };

            Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("chnking", "Custom"), roles);

        }

        else

        {

            throw(new SecurityTokenException("用户名或密码无效!"));

        }

    }

}

这部分代码有几处需要说明:

客户端使用UserName验证方式,在服务端可以使用对客户端发送来的UserName的验证方式有三种:

Windows:用windows的帐号和密码验证客户端送来的UserName

MembershipProvider:提供基于已配置的MembershipProvider的密码验证。

Custom:由自定义的从UserNamePasswordValidator继承来的类验证用户名和密码。

本例中选用自定义验证,并新建了一个从UserNamePasswordValidator继承来的类customUserNamePasswordValidator来验证客户端用户名和口令。

验证了用户正确后,新建一个跟此用户对应的GenericPrincipal,包括这个用户的Identity,这里叫做”chnking”,和这个identity所属的角色,这里这个用户同时属于"admin", "operator"。还把这个用户的GenericPrincipal赋给了Thread.CurrentPrincipal,使本线程往下的运行上下文切换到这个定制的GenericPrincipal

还有一点,服务端的PrincipalPermissionMode默认是UseWindowsGroups,这表示将Thread.CurrentPrincipal设置为WindowsPrincipal,一般是windows验证时映射到windows用户。本例需要自己设置Thread.CurrentPrincipal,故此处设置为None,否则,到了执行服务端services代码时,Thread.CurrentPrincipal将为空。

3.3.3.   客户端代码

static void Main(string[] args)

{

    NetTcpBinding myBinding = new NetTcpBinding();

    myBinding.Security.Mode = SecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

    EndpointAddress ea = new EndpointAddress("net.tcp://jinjz2008:8056/WCFService/GetIdentity");

    GetIdentityClient gc = new GetIdentityClient(myBinding, ea);

    //不验证服务端证书的有效性

    gc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =

        System.ServiceModel.Security.X509CertificateValidationMode.None;

    //提供UserName客户端用户凭据

    gc.ClientCredentials.UserName.UserName = "chnking";

    gc.ClientCredentials.UserName.Password = "jjz666";

    //为使用TcpTrace跟踪消息设置的TcpTrace监听端口

    ClientViaBehavior myClientViaBehavior = new ClientViaBehavior

        (new Uri("net.tcp://jinjz2008:8055/WCFService/GetIdentity"));

    gc.Endpoint.Behaviors.Add(myClientViaBehavior);

    //执行代理类Get方法

    string result = gc.Get(WindowsIdentity.GetCurrent().Name);

    Console.WriteLine(result);

    Console.ReadLine();

}

客户端没有太多需要特别说明的。设置客户端验证方式为UserName后用以下代码提供用户名和口令:

    //提供UserName客户端用户凭据

    gc.ClientCredentials.UserName.UserName = "chnking";

    gc.ClientCredentials.UserName.Password = "jjz666";

3.3.4.   测试

clip_image006

可以看出,客户端的chnking身份被传送到服务端。并且,有权限执行服务端的Get方法。

3.3.5.   身份模拟和访问权限控制

如果在服务端的Get方法中设置一个断点,如下图:

clip_image008

可以看到当代码运行到Get方法中时,当前线程的Principal就是在customUserNamePasswordValidator定制类中赋给的chnking,并且这个chnking属于admin角色。

如果把Get的权限改一下,改成只有叫”manager”的角色可以方法此方法:

    [PrincipalPermission(SecurityAction.Demand, Role = " manager ")]

    public string Get(string ClientIdentity)

再看运行结果:

clip_image010

Chning不属于”manager”角色,也就没有执行Get方法的权限。

3.4.   客户端验证:Certificate

这部分的测试代码: NetTcpBinding_Message_Certificate.rar

netTCPBinding绑定的Message安全模式,客户端Certificate验证,此时将使用服务端证书,通过WS-Trust协议建立的安全通道,原理上类似SSLTLS的机制(但不是通过网络传输层来实现,而是通过处理SOAP中的消息)来保证消息的安全性。

这种方式的安全性:

完整性

使用服务端证书,通过WS-Trust协议建立的安全通道

保密性

使用服务端证书,通过WS-Trust协议建立的安全通道

服务端身份身份验证

服务端证书提供

客户端身份验证

客户端证书提供

3.4.1.   获得和安装证书

同时客户端验证设置为Certificate,就需要提供客户端证书以验证客户端身份。

所有这里需要在服务端和客户端分别安装证书。

这里用Makecert.exe工具生成证书,使用下面的命令:

makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe -r

这是服务端证书,win2008是服务端的机器名。

如果做过前面BasicHttpBinding的测试,这个服务端证书就应该已经有了。

makecert -sr currentuser -ss My -n CN=TestClient -sky exchange -pe -r

这是客户端证书。

3.4.2.   服务端代码

internal static ServiceHost myServiceHost = null;

internal static void Main()

{

    NetTcpBinding myBinding = new NetTcpBinding();

    myBinding.Security.Mode = SecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

    Uri baseAddress = new Uri("net.tcp://localhost:8056/WCFService/");

    myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);

    ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint

        (typeof(IGetIdentity), myBinding, "GetIdentity");

    //设置服务端证书

    myServiceHost.Credentials.ServiceCertificate.SetCertificate("CN=win2008");

    //设置不验证客户端证书的有效性

    myServiceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode =

        System.ServiceModel.Security.X509CertificateValidationMode.None;

    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

    behavior.HttpGetEnabled = true;

    behavior.HttpGetUrl = new Uri("http://localhost:8057/mex");

    myServiceHost.Description.Behaviors.Add(behavior);

    myServiceHost.Open();

    Console.WriteLine("Service started!");

    Console.ReadLine();

    myServiceHost.Close();

}

3.4.3.   客户端代码

static void Main(string[] args)

{

    NetTcpBinding myBinding = new NetTcpBinding();

    myBinding.Security.Mode = SecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

    EndpointAddress ea = new EndpointAddress("net.tcp://win2008:8056/WCFService/GetIdentity");

    GetIdentityClient gc = new GetIdentityClient(myBinding, ea);

    //设置客户端证书

    gc.ClientCredentials.ClientCertificate.SetCertificate("CN=TestClient",

        StoreLocation.CurrentUser, StoreName.My);

    //设置不验证服务端证书有效性

    gc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =

        System.ServiceModel.Security.X509CertificateValidationMode.None;

    //为使用TcpTrace跟踪消息设置的TcpTrace监听端口

    ClientViaBehavior myClientViaBehavior = new ClientViaBehavior

        (new Uri("net.tcp://win2008:8055/WCFService/GetIdentity"));

    gc.Endpoint.Behaviors.Add(myClientViaBehavior);

    //执行代理类Get方法

    string result = gc.Get(WindowsIdentity.GetCurrent().Name);

    Console.WriteLine(result);

    Console.ReadLine();

}

3.4.4.   测试

clip_image012

由于客户端是Certificate身份验证,到了服务端 ServiceSecurityContext.Current. PrimaryIdentity.Name获得的是证书的subject name和证书指纹。

3.4.5.   证书映射到windows用户

有时需要把客户端证书映射为服务端的windows用户,这样可以使用windows权限控制客户端在服务端的权限。

在本例的情况,可以设置客户端证书跟服务端windows用户的映射,首先在服务端的代码或配置文件中设置允许客户端证书到服务端windows用户的映射。

代码中将客户端验证MapClientCertificateToWindowsAccount设为True

myServiceHost.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;

配置文件中将服务端Behavior的客户端证书验证MapClientCertificateToWindowsAccount设为True

<serviceBehaviors>

     <behavior>

         <serviceCredentials>

              <clientCertificate>

                   <authentication certificateValidationMode="None" mapClientCertificateToWindowsAccount="True" />

              </clientCertificate>

         </serviceCredentials>

     </behavior>

</serviceBehaviors>

然后在服务端设置映射,在操作系统上把客户端的证书与windows用户作映射,这必须是要在安装了Active Directory的服务器上做。

具体步骤参考文章:Map certificates to user accounts