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

时间:2015-04-28 22:50:02

标签: wcf wcf-security

我尝试配置WCF服务以实现双因素身份验证。我们的想法是使用用户名/密码(WS安全性)进行消息级别身份验证,并使用客户端证书进行传输级别身份验证。

第1步:消息级别身份验证

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

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

  • AuthenticationType = Basic
  • ImpersonationLevel = Impersonation
  • IsAnonymous = false
  • IsAuthenticated = true
  • 名称=我的广告帐户(DOMAIN \ accountname)

System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity对象也是一个windowsIdentity,具有与上面相同的属性值。

步骤2:使用证书进行传输级别身份验证

然后我构建了一个新的WCF服务,它使用带证书的传输身份验证。同样,一切都很棒。

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

  • AuthenticationType = X509
  • IsAuthenticated = true
  • Name =证书的主题属性,指纹

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

  • 身份验证类型=""
  • ImpersonationLevel = Anonymous
  • IsAnonymous = true
  • IsAuthenticated = false

步骤3:使用证书和&amp ;;传输级别身份验证活动目录映射

接下来,我通过创建服务行为并将serviceCredientials \ clientCertificate \ authentication mapClientCertificateToWindowsAccount属性设置为true来启用活动目录映射。

该服务似乎正确地将证书映射到我的活动目录帐户。

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

  • AuthenticationType = SSL / PCT
  • ImpersonationLevel =身份识别
  • IsAnonymous = false
  • IsAuthenticated = true
  • 名称=我的广告帐户(DOMAIN \ accountname)

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类型,具有以下属性值:

  • 身份验证类型=&#34;&#34;
  • IsAuthenticated = false
  • 姓名=&#34;&#34;

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

  • AuthenticationType = X509
  • IsAuthenticated = true
  • Name =证书的主题属性,指纹

所以此时,我可以看到证书凭据的详细信息,但不能看到消息凭据的详细信息。这是我的第一个问题 - 为什么我看不到消息级别凭据?

步骤5:使用AD映射的邮件级别身份验证和传输身份验证。

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

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

  • 身份验证类型=&#34;&#34;
  • IsAuthenticated = false
  • 姓名=&#34;&#34;

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

  • AuthenticationType =&#34;&#34;
  • ImpersonationLevel = Anonymous
  • IsAuthenticated = false
  • IsAnonymous = true
  • 姓名=&#34;&#34;

身份验证似乎在传输和消息级别都正确发生。如果我在soap标题中指定了错误的用户名/密码,我将收到一个soap故障。如果我不提供客户端证书,或提供不受信任的证书,我也会收到错误消息 所以在这里,我了解System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity将是一个System.Security.Principal.WindowsIdentity类型,因为该服务配置为映射到AD帐户,但为什么它实际上没有映射?

0 个答案:

没有答案