WCF,使用证书进行传输身份验证,使用用户名/密码进行消息身份验证

WCF,使用证书进行传输身份验证,使用用户名/密码进行消息身份验证,wcf,wcf-security,Wcf,Wcf Security,我正在尝试配置WCF服务以实现双因素身份验证。其思想是使用用户名/密码WS-security进行消息级身份验证,使用客户端证书进行传输级身份验证 步骤1:消息级身份验证 我构建了一个WCF服务,它使用带有用户名/密码的消息级身份验证。一切都很好。我在soap头中看到了从客户端传递的凭据,服务对用户进行身份验证和授权 System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Princi

我正在尝试配置WCF服务以实现双因素身份验证。其思想是使用用户名/密码WS-security进行消息级身份验证,使用客户端证书进行传输级身份验证

步骤1:消息级身份验证

我构建了一个WCF服务,它使用带有用户名/密码的消息级身份验证。一切都很好。我在soap头中看到了从客户端传递的凭据,服务对用户进行身份验证和授权

System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Principal.WindowsIdentity类型,具有以下属性值:

AuthenticationType=Basic 模拟级别=模拟 IsAnonymous=false IsAuthenticated=true Name=我的广告帐户域\帐户名 System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象也是一个WindowsIdentity对象,具有与上述相同的属性值

步骤2:使用证书的传输级身份验证

然后,我构建了一个新的WCF服务,它使用带有证书的传输身份验证。再说一遍,一切都很好

System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.IdentityModel.Claims.X509Identity类型,具有以下属性值:

AuthenticationType=X509 IsAuthenticated=true Name=证书的subject属性,指纹 System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象是System.Security.Principal.WindowsIdentity类型,具有以下属性值:

身份验证类型= ImpersonationLevel=匿名 IsAnonymous=真 IsAuthenticated=false 步骤3:使用证书和active directory映射的传输级身份验证

接下来,我通过创建服务行为并将serviceCredientials\clientCertificate\authentication mapClientCertificateToWindowsAccount属性设置为true来打开active directory映射

该服务似乎正确地将证书映射到我的active directory帐户

System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Principal.WindowsIdentity类型,具有以下属性值:

AuthenticationType=SSL/PCT 模拟级别=标识 IsAnonymous=false IsAuthenticated=true Name=我的广告帐户域\帐户名 System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象也是一个WindowsIdentity对象,具有与上述相同的属性值

步骤4:消息级身份验证和传输身份验证

随着上述场景的运行,我现在想将它们结合起来。A创建了具有用户名密码消息级身份验证和证书传输身份验证的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.GenericEntity类型,具有以下属性值:

身份验证类型= IsAuthenticated=false 姓名= System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象是System.IdentityModel.Claims.X509Identity类型,具有以下属性值:

AuthenticationType=X509 IsAuthenticated=true Name=证书的subject属性,指纹 所以在这一点上,我可以看到证书凭据的详细信息,但不能看到消息凭据的详细信息。这是我的第一个问题-为什么我看不到消息级凭据

步骤5:消息级身份验证和带有AD映射的传输身份验证

现在,我通过将serviceCredientials\clientCertificate\authentication mapClientCertificateToWindowsAccount属性设置为true来启用AD用户映射

System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity对象是System.Security.Principal.GenericEntity类型,具有以下属性值:

身份验证类型= IsAuthenticated=false 姓名= System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象是System.Security.Principal.WindowsIdentity类型,具有以下属性值:

AuthenticationType= ImpersonationLevel=匿名 IsAuthenticated=false IsAnonymous=真 姓名= 身份验证似乎在传输和消息级别都正确进行。如果我在soap头中指定了错误的用户名/密码,我将返回一个soap错误。如果我没有提供客户端证书,或者提供了一个不受信任的证书,我也会得到一个错误 因此,在这里,我理解System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity将是System.Security.Principal.WindowsIdentity类型,因为该服务配置为映射到AD帐户,但为什么没有 真的没有地图吗