【问题标题】:Is there a way to call a Web Service with Client and Service Certificates in powershell?有没有办法在 powershell 中调用带有客户端和服务证书的 Web 服务?
【发布时间】:2021-04-13 13:21:22
【问题描述】:

我正在编写一个 Powershell 脚本,该脚本需要调用一个带有客户端和服务证书的 Web 服务。 我在 C# .Net 中有连接半工作。 在 .Net app.config 我有这些配置:

...
<security mode="TransportWithMessageCredential">
            <message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false"/>
            <transport clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="CertificateAuthenticationBehavior">
          <clientCredentials>
            <clientCertificate findValue="Capital Market FIONAsi" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            <serviceCertificate>
              <defaultCertificate findValue="example.dk" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
              <authentication certificateValidationMode="PeerTrust" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>

.net 代码。

var stinaProxy = new StinaServiceProxy("StinaService");
var stinaHandshakeResponse = stinaProxy.HandShake(testValueArgument);

这似乎让我通过了 .net 中的证书验证

但如前所述,我实际上需要它在 powershell 中为我工作。 我不知道如何调用 Web 服务并提供客户端和服务证书。

这是我到目前为止在 powershell 中得到的结果,但它以超时结束,我认为是证书问题。

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

    $ClientCertificate = Get-ChildItem Cert:\LocalMachine\My\af4269b1d7190be23f1e48001fc345011f7ade80
    $defaultCertificate = Get-ChildItem Cert:\LocalMachine\My\42097f29a5bd2fb4d9960e74f67654d369b7a2e3
    $url = "https://example.dk/StinaService.svc?wsdl"
    $webserviceex = New-WebServiceProxy -Uri $url -Namespace WebServiceProxy 
    $webserviceex.Timeout = 5000
    $webserviceex.ClientCertificates.Add($ClientCertificate)
    $webserviceex.ClientCertificates.Add($defaultCertificate)
    $handshakeResult = $webserviceex.HandShake("1234!")

任何帮助表示赞赏:)

【问题讨论】:

  • 服务证书是什么意思?看起来您正确地进行了客户端证书身份验证,但我不确定 $defaultCertificate 应该用于什么。您是否有权访问网络服务以查看它为什么不响应?通常,错误/丢失的证书应返回 403。
  • 我猜您的客户正在检查服务证书的有效性,并且在吊销列表检查中失败或超时。我认为您不需要将$defaultcertificate 添加到ClientCertficates 集合中,您只需要信任服务证书即可。您是否尝试将PeerTrust 属性添加到您的$webservicex proxy
  • 大家好,感谢您的意见。
  • 大家好,感谢您的意见。 Cpt.Whale,我想我需要两个证书,但我不擅长这个证书的东西。我无权访问网络服务后端/日志。 RichMoss,实际上我不相信将它添加到 ClientCertificates 集合是诀窍,只是我的尝试。我已将证书添加到机器商店。我看不到在 powershell 中添加 PeerTrust 的可能性。你知道怎么做吗?

标签: powershell web-services certificate servicepointmanager new-webserviceproxy


【解决方案1】:

我怀疑ServiceCertificate 是否会成为您问题的原因,因为只有客户才应该关心。您是否尝试过添加$ClientCertificate 来设置$webserviceex?通常,如果您有链并且还需要 CA 证书,您只会添加额外的证书。


我确实找到了如何在 powershell 中添加服务证书。您没有包含您使用的类,但我能够使用 [System.ServiceModel.ServiceHost] 创建与您所拥有的类似的东西。这是一个使用客户端和服务器证书的 web 服务的 powershell 示例。

[URI]$URI = 'https://example.dk/StinaService.svc'

# WSHttpBinding
$binding = New-Object System.ServiceModel.WSHttpBinding
$binding.Security.Mode = [System.ServiceModel.SecurityMode]::TransportWithMessageCredential
$binding.Security.Transport.ClientCredentialType = [System.ServiceModel.HttpClientCredentialType]::Certificate
$binding.Security.Message.ClientCredentialType   = [System.ServiceModel.MessageCredentialType]::Certificate

# Create service host
$ServiceHost = [System.ServiceModel.ServiceHost]::new([StinaService], $URI)
    $ServiceHost.AddServiceEndpoint([IStinaService], $binding,"")

    # Add Service Certificate (authenticate the server)
    $ServiceHost.Credentials.ServiceCertificate.SetCertificate(
        [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine,
        [System.Security.Cryptography.X509Certificates.StoreName]::My,
        [System.Security.Cryptography.X509Certificates.X509FindType]::FindBySubjectName,
        'example.dk'
    )
    # Add Client Certificate (authenticate the client)
    $ServiceHost.Credentials.ClientCertificate.SetCertificate(
        [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine,
        [System.Security.Cryptography.X509Certificates.StoreName]::My,
        [System.Security.Cryptography.X509Certificates.X509FindType]::FindBySubjectName,
        'Capital Market FIONAsi' 
    )

# Open the service
$ServiceHost.Open()

# Close the service.
$ServiceHost.Close()

我基于示例 .net WCF 代码 in this MS how-to,并使用 Chrissy Lemaire 在她的 powershell tcp service proof-of-concept 中的定义定义了 [StinaService] ServiceContract。


请注意,您可能可以忽略此示例 - 只需复制现有的 .Net 代码,将其格式化为 powershell,然后导入您已在使用的相同 app.config。

[System.AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "$dllPath.config")
$null = [Reflection.Assembly]::LoadFrom($dllPath)

复制自https://stackoverflow.com/a/33927024/7411885

【讨论】:

  • 谢谢Cpt。鲸鱼 这似乎是您的 powershell 示例的正确方法。我必须先添加这一行: Add-Type -AssemblyName System.ServiceModel 但是脚本无法运行这一行: $ServiceHost = [System.ServiceModel.ServiceHost]::new([StinaService], $URI) 无法找到输入 [StinaService]。
  • @SimonBruun 抱歉,我对实际的服务定义和绑定步骤不是很熟悉。如果您使用的是 wsdl,AddServiceEndpoint() 可能不是您所需要的。
猜你喜欢
  • 2014-09-06
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
  • 2011-03-30
相关资源
最近更新 更多