同时使用用户名和证书的WCF消息身份验证
长话短说: 我的WCF客户端应该能够向IIS中托管的服务提供用户名和证书,在IIS中,我应该使用这些信息使用自定义策略验证请求 完整故事: 我需要对一些WCF客户端进行身份验证,以验证它们是否可以执行操作 我们有两种客户机:WPF应用程序和web应用程序。我们希望做到以下几点:同时使用用户名和证书的WCF消息身份验证,wcf,iis-7,wcf-binding,wcf-security,x509certificate,Wcf,Iis 7,Wcf Binding,Wcf Security,X509certificate,长话短说: 我的WCF客户端应该能够向IIS中托管的服务提供用户名和证书,在IIS中,我应该使用这些信息使用自定义策略验证请求 完整故事: 我需要对一些WCF客户端进行身份验证,以验证它们是否可以执行操作 我们有两种客户机:WPF应用程序和web应用程序。我们希望做到以下几点: web应用程序使用服务信任的证书,以便将其识别为具有所有权限的特殊用户(web应用程序已自行验证权限,我们现在不想碰它) WPF客户端使用用户提供的用户名/密码进行身份验证 在操作的实现中,我想验证是否提供了证书(然
- web应用程序使用服务信任的证书,以便将其识别为具有所有权限的特殊用户(web应用程序已自行验证权限,我们现在不想碰它)
- WPF客户端使用用户提供的用户名/密码进行身份验证
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SecureBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="Test"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="AuthenticationProtectedService.Security.CertificateValidator, AuthenticationProtectedService.Security"/>
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="AuthenticationProtectedService.Security.UserNamePassValidator, AuthenticationProtectedService.Security" />
</serviceCredentials>
<serviceAuthorization serviceAuthorizationManagerType="AuthenticationProtectedService.Security.CertificateAuthorizationManager, AuthenticationProtectedService.Security"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding>
<security mode="None"/>
</binding>
<binding name="SecureNetTcp">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<service
name="AuthenticationProtectedService.Services.OneWayServiceB"
behaviorConfiguration="SecureBehavior">
<endpoint
address=""
binding="wsHttpBinding"
contract="AuthenticationProtectedService.ServiceModel.IOneWayServiceB">
</endpoint>
</service>
<service
name="AuthenticationProtectedService.Services.DuplexServiceB" behaviorConfiguration="SecureBehavior">
<endpoint
address=""
binding="netTcpBinding"
bindingConfiguration="SecureNetTcp"
contract="AuthenticationProtectedService.ServiceModel.IDuplexServiceB">
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
我认为问题可能出在服务配置的nettcpbinding.Security.Message节点的clientCredentialType属性中,但我看不到在消息安全性中同时使用证书和用户名的选项
谢谢你的帮助
备注:本项目的一个具体目标是对服务器设置和系统的总体影响非常低,因此,如果可能,也应避免使用SSL。尝试此链接……它可能会解决您的问题,您可以为相同的绑定类型使用不同的绑定配置,并根据需要将相同的绑定配置关联到不同的端点。您好!谢谢,这正是我所做的,但我忘了更新问题。最后,指定不同的端点就足够了。无论如何,我会把这个作为答案,因为它指向了正确的方向。
public static void SetCertificate(this ClientCredentials loginCredentials)
{
loginCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "SecureWcfClient");
}
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SecureBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="Test"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="AuthenticationProtectedService.Security.CertificateValidator, AuthenticationProtectedService.Security"/>
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="AuthenticationProtectedService.Security.UserNamePassValidator, AuthenticationProtectedService.Security" />
</serviceCredentials>
<serviceAuthorization serviceAuthorizationManagerType="AuthenticationProtectedService.Security.CertificateAuthorizationManager, AuthenticationProtectedService.Security"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding>
<security mode="None"/>
</binding>
<binding name="SecureNetTcp">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<service
name="AuthenticationProtectedService.Services.OneWayServiceB"
behaviorConfiguration="SecureBehavior">
<endpoint
address=""
binding="wsHttpBinding"
contract="AuthenticationProtectedService.ServiceModel.IOneWayServiceB">
</endpoint>
</service>
<service
name="AuthenticationProtectedService.Services.DuplexServiceB" behaviorConfiguration="SecureBehavior">
<endpoint
address=""
binding="netTcpBinding"
bindingConfiguration="SecureNetTcp"
contract="AuthenticationProtectedService.ServiceModel.IDuplexServiceB">
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
public class CertificateAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
if (!base.CheckAccessCore(operationContext))
{
return false;
}
string thumbprint = GetCertificateThumbprint(operationContext);
// I'd need to verify the thumbprint, but it is always null
return true;
}
private string GetCertificateThumbprint(OperationContext operationContext)
{
foreach (var claimSet in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
{
foreach (Claim claim in claimSet.FindClaims(ClaimTypes.Thumbprint, Rights.Identity))
{
string tb = BitConverter.ToString((byte[])claim.Resource);
tb = tb.Replace("-", "");
return tb;
}
}
return null;
}
}