设置 IIS 以要求客户端证书并使用匿名身份验证

设置 IIS 以要求客户端证书并使用匿名身份验证

设置 IIS 以要求客户端证书并使用匿名身份验证

我有一个 WCF Web 服务供我们的客户使用。我想使用客户端证书来保护它。我还将使用客户端证书来识别客户。

我已经使识别部分工作正常,但是无法使 IIS 需要客户端证书。

如果我将 IIS 设置为接受客户端证书,则通信可以正常进行,并且我可以使用以下方法获取客户端身份:

ServiceSecurityContext.Current.PrimaryIdentity.Name

但我也可以在没有客户端证书的情况下访问该网站。我不确定那些没有证书的人除了读取 WSDL 之外还能做什么,但我不希望没有受信任证书的人能够获取任何信息。

如果我将 IIS 设置为需要客户端证书,那么应该具有访问权限的测试客户端会收到错误:

使用客户端身份验证方案‘匿名’时,HTTP 请求被禁止。

我希望只允许拥有服务器信任的客户端证书的用户访问。其他用户将被拒绝。

服务器 WCF 配置:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="DefaultBehavior">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceCredentials>
          <clientCertificate>
            <authentication certificateValidationMode="ChainTrust" />
          </clientCertificate>
          <serviceCertificate findValue="64343ee2c8338518e78ba698f3936dc92c90db57" x509FindType="FindByThumbprint" />
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name="DefaultBinding">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="Certificate" />
          <message clientCredentialType="Certificate" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <services>
    <service name="WebService.Service" behaviorConfiguration="DefaultBehavior">
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="DefaultBinding" contract="WebService.IService" />
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
  </services>
</system.serviceModel>

客户端 WCF 配置。

<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="DefaultBehavior">
        <clientCredentials>
          <clientCertificate storeLocation="LocalMachine" findValue="d084c91a8f81878cd4dd991bbab348235f0fd1a3" x509FindType="FindByThumbprint" />
          <serviceCertificate>
            <authentication certificateValidationMode="ChainTrust" />
          </serviceCertificate>
        </clientCredentials>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name="WSHttpBinding_IService">
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="Certificate" />
          <message clientCredentialType="Certificate" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <client>
    <endpoint address="https://host/WebService/Service.svc"
      behaviorConfiguration="DefaultBehavior" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
      contract="WebService.IService" name="WSHttpBinding_IService">
    </endpoint>
  </client>
</system.serviceModel>

答案1

好的,我们做了和你一样的事情。我们反过来做。我们首先使用客户端和服务器证书保护 IIS。我们在 IIS Express 上执行了此操作(我发布此文时仍在开发中)。我们允许在 IIS Express 中applicationhost.config覆盖 web.config 的特定部分。即:<section name="windowsAuthentication" overrideModeDefault="Allow" />

服务器端配置:

<sytem.serviceModel>
<bindings>
      <wsHttpBinding>
        <binding name="ClientCert">
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
</bindings>
<behaviors>
<!--We have a custom service behavior for claim based security -->
        <behavior name="wsHttpCertificateBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
          <serviceAuthorization serviceAuthorizationManagerType="MyNamespace.AdamAuthorizationManager, MyAssembly">
            <authorizationPolicies>
              <add policyType="MyNamespace.AdamAuthorizationPolicy, MyAssembly" />
            </authorizationPolicies>
          </serviceAuthorization>
          <serviceCredentials>
            <serviceCertificate findValue="YourServerCertificateNameWithoutCN=" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
            <clientCertificate>
              <authentication revocationMode="NoCheck" mapClientCertificateToWindowsAccount="true" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
</behaviors>
<services>
      <service name="MyNamespace.OrderService" behaviorConfiguration="wsHttpCertificateBehavior">
        <endpoint address="https://iisurl/OrderService.svc/ClientCert" contract="wsHttpCertificateBehavior.IOrderService" binding="wsHttpBinding" bindingConfiguration="ClientCert">
        </endpoint>
      </service>
</services>
</sytem.serviceModel>
<system.webServer>
<security>
      <authentication>
        <windowsAuthentication enabled="true" />
        <anonymousAuthentication enabled="true" />
        <iisClientCertificateMappingAuthentication defaultLogonDomain="YourDomain" enabled="true" oneToOneCertificateMappingsEnabled="true">
          <oneToOneMappings>
            <add enabled="true" certificate="Base64HashOfTheCertificate" userName="YourUserName" password="YourPassword" />
          </oneToOneMappings>
        </iisClientCertificateMappingAuthentication>
      </authentication>
      <authorization>
        <add users="*" accessType="Allow" />
      </authorization>
      <!--Require SSL *AND* require a client certificate -->
      <access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
    </security>
</system.WebServer>

在客户端上:

<system.serviceModel>
      <wsHttpBinding>
        <binding name="ClientCertificate">
          <security mode="Transport">
            <transport clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    <behaviors>
      <endpointBehaviors>
        <behavior name="wsHttpCertificateBehavior">
          <clientCredentials>

            <clientCertificate findValue="YourClientCertificateNameWithoutCN=" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
            <serviceCertificate>
              <authentication revocationMode="NoCheck"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <client>

      <endpoint name="ClientCertificate" address="https://iisurl/OrderService.svc/ClientCert" contract="MyNamespace.IOrderService" binding="wsHttpBinding" bindingConfiguration="ClientCertificate" behaviorConfiguration="wsHttpCertificateBehavior">
      </endpoint>
    </client>
</system.serviceModel>

对我们帮助很大的是启用跟踪、服务中的日志记录和自定义授权策略以及 IIS 跟踪日志。

我们已经iisurl在主机文件中映射到 127.0.0.1,因此我们拥有可信证书。对于 iisClientCertificationMapping 检查出去。

不知道您的 SSL 设置是否正确。我们有一个适用于此的 powershell 脚本。其中部分内容如下:

生成根证书(powershell)

Invoke-Command -ScriptBlock{ . "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\makecert.exe" -n "CN=YourRootCA" -r -sv YourRootCA.pvk YourRootCA.cer}


    $certFile = get-childitem $exPath | where {$_.FullName -match "GlobalVisionServicesRootCA.cer"} 
    if ($certFile -ne $NULL) { 
        echo "Discovered the YourRootCA.cer in the same folder as this script, installing it in the LocalMachine\Root certificate store.." 
        $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certFile.FullName)
        $rootStore = new-object system.security.cryptography.x509certificates.x509Store 'Root','LocalMachine'
        $rootStore.Open('ReadWrite')
        $rootStore.Add($cert) 
        $rootStore.Close() 
    }

生成服务器证书(命令行):

makecert.exe  -sk YourDevSrvCert -iv YourRootCA.pvk -n "CN=iisurl" -ic YourRootCA.cer -sr localmachine -ss my -sky exchange -pe yourservercertificate.cer

生成服务器客户端(命令行):

makecert.exe  -sk ClientDevSrvCert -iv YourRootCA.pvk -n "CN=iisurl" -ic GlobalVisionServicesRootCA.cer -sr localmachine -ss my -sky exchange -pe iisurl.cer

将证书绑定到 IIS (命令行,特定于 XP):

httpcfg.exe delete ssl -i "0.0.0.0:443"
httpcfg.exe" delete urlacl url="https://iisurl:443/"

httpcfg.exe set urlacl url="https://iisurl:443/" user=Everyone
httpcfg.exe" set ssl -i "0.0.0.0:443" -h ThumpPrint

将 ThumpPrint 更改为主题名为 iisurl 的证书的 ThumpPrint。我建议您使用 powershell 完全自动化此操作,我们也有这个,所以我们可以在多台机器上进行开发。但我无法在这里全部完成。

希望这对您有所帮助。使用此配置,如果您通过 https 浏览 URL iisurl/OrderService,它会要求您提供客户端证书。(在 IE 中)

您还可以查看此日志:C:\WINDOWS\system32\Logfiles\HTTPERR

相关内容