我尝试配置WCF服务以实现双因素身份验证。我们的想法是使用用户名/密码(WS安全性)进行消息级别身份验证,并使用客户端证书进行传输级别身份验证。
第1步:消息级别身份验证
我已经构建了一个使用用户名/密码进行消息级别身份验证的WCF服务。一切都很棒。我在soap标头中看到从客户端传递的凭据,服务对用户进行身份验证和授权。
System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Principal.WindowsIdentity类型,具有以下属性值:
System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象也是一个windowsIdentity,具有与上面相同的属性值。
步骤2:使用证书进行传输级别身份验证
然后我构建了一个新的WCF服务,它使用带证书的传输身份验证。同样,一切都很棒。
System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.IdentityModel.Claims.X509Identity类型,具有以下属性值:
System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象是System.Security.Principal.WindowsIdentity类型,并具有以下属性值:
步骤3:使用证书和&amp ;;传输级别身份验证活动目录映射
接下来,我通过创建服务行为并将serviceCredientials \ clientCertificate \ authentication mapClientCertificateToWindowsAccount属性设置为true来启用活动目录映射。
该服务似乎正确地将证书映射到我的活动目录帐户。
System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Principal.WindowsIdentity类型,具有以下属性值:
System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象也是一个windowsIdentity,具有与上面相同的属性值。
第4步:邮件级别身份验证和传输身份验证
在上述方案有效的情况下,我现在想要将它们结合起来。创建了一个Web服务,其中包含用户名密码消息级别身份验证和证书传输身份验证,并禁用了Active Directory用户映射。
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="WCFTransportAuthCertificateMessageAuthUserName.Service1"
behaviorConfiguration="MapClientCertificates">
<endpoint binding="customBinding"
bindingConfiguration="TransportCertificateAuthentication_MessageUserNameAuthenticiation"
contract="WCFTransportAuthCertificateMessageAuthUserName.IService1">
</endpoint>
</service>
</services>
<bindings>
<customBinding>
<binding name="TransportCertificateAuthentication_MessageUserNameAuthenticiation">
<textMessageEncoding messageVersion="Soap11"></textMessageEncoding>
<security authenticationMode="UserNameOverTransport"></security>
<httpsTransport requireClientCertificate="true"></httpsTransport>
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="MapClientCertificates">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<clientCertificate>
<authentication mapClientCertificateToWindowsAccount="false" includeWindowsGroups="true" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Principal.GenericIdentity类型,具有以下属性值:
System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象是System.IdentityModel.Claims.X509Identity类型,并具有以下属性值:
所以此时,我可以看到证书凭据的详细信息,但不能看到消息凭据的详细信息。这是我的第一个问题 - 为什么我看不到消息级别凭据?
步骤5:使用AD映射的邮件级别身份验证和传输身份验证。
现在,我通过将serviceCredientials \ clientCertificate \ authentication mapClientCertificateToWindowsAccount属性设置为true来启用AD用户映射。
System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Principal.GenericIdentity类型,具有以下属性值:
System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象是System.Security.Principal.WindowsIdentity类型,并具有以下属性值:
身份验证似乎在传输和消息级别都正确发生。如果我在soap标题中指定了错误的用户名/密码,我将收到一个soap故障。如果我不提供客户端证书,或提供不受信任的证书,我也会收到错误消息 所以在这里,我了解System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity将是一个System.Security.Principal.WindowsIdentity类型,因为该服务配置为映射到AD帐户,但为什么它实际上没有映射?