如何使用 WCF 连接 Apple 的 GSX NewGeneration Web 服务?

How can I connect with Apple's GSX NewGeneration webservices with WCF?

从 2015 年 8 月 15 日开始,Apple 的 GSX 网络服务将升级到更安全的版本,每个请求都需要客户端 SSL 证书。我需要采取哪些步骤才能使用 WCF 框架和 C#.NET 连接到这个新一代 Web 服务?

Apple 的文档指出第一步是生成 CSR(证书签名请求),将其发送给 Apple,他们将return 一个证书以确保未来连接的安全。

如何生成此 CSR?接下来我需要采取哪些步骤才能成功连接并获得有效响应?

以上和之前的Find My iPhone webservice实现给我造成了比较大的麻烦,希望对其他用户有所帮助。

(N.B。我想添加 apple-gsx 标签,但我没有所需的信誉)

为了成功调用网络服务,需要执行以下步骤:

  1. 确保您已 OpenSSL 安装并正常工作
  2. 生成密钥对:
    openssl genrsa -aes256 -out [NameOfPrivateKey].pem 2048
    保留此私钥 PRIVATE,不要与任何人分享!
  3. 出现提示时,select输入安全密码并妥善保管。
  4. 生成证书签名请求 (CSR):
    openssl req -new -sha256 -key [NameOfPrivateKeyFromStep2].pem -out [NameOfTheSigningRequest].csr
    当上述命令失败并显示“警告:无法打开配置文件:/usr/local/ssl/openssl.cnf”时 运行 命令 set OPENSSL_CONF=c:\[PATH TO YOUR OPENSSL DIRECTORY]\bin\openssl.cfg 在管理员命令提示符下)
  5. 将 .csr(证书签名请求)发送给 Apple,将 .key 保密。 Apple returns .pem 证书文件
  6. 确保.pem 和.key 的MD5 匹配。以下命令的输出应该相同:

    openssl x509 -noout -modulus -in [CertificateReceivedFromApple].pem | openssl md5

    openssl rsa -noout -modulus -in [NameOfPrivateKeyFromStep2].pem | openssl md5

  7. 将证书和密钥合并到一个 .p12 容器中 (More info here)

    openssl pkcs12 -export -in [CertificateReceivedFromApple].pem -inkey [NameOfPrivateKeyFromStep2].pem -out [FilenameOfNewKeyContainer].p12

  8. 出现提示时,select输入安全密码并妥善保管。

  9. 让VisualStudio生成一个代理class,基于你可以从Apple下载的WSDL文件,例如调用它GsxWSEmeaAspService

  10. 使用下面的代码验证您自己。进一步调用实际发送或接收数据需要 userSessionId

    public void Authenticate() {
        using (GsxWSEmeaAspService client = new GsxWSEmeaAspService()) {
            X509Certificate2 cert = new X509Certificate2(
                [PathToContainerFromStep7].p12"),
                [YourPasswordFromStep8],
                X509KeyStorageFlags.MachineKeySet);
            client.ClientCertificates.Add(cert);
    
            GsxWSEmeaAspService.authenticateRequestType req = new GsxWSEmeaAspService.authenticateRequestType();
            req.languageCode = "EN";
            req.serviceAccountNo = [YourAppleServiceAccountNumber];
            req.userId = [YourUserID];
            req.userTimeZone = "CEST";
    
            client.Proxy = null;
    
            GsxWSEmeaAspService.authenticateResponseType res = client.Authenticate(req);
            userSessionId = res.userSessionId;
        }
    }
    
  11. 确保您没有运行任何 http 代理,例如 Fiddler,因为当代理处于活动状态时请求会失败。 运行在 SoapUI 中设置请求也是如此:需要关闭代理设置。

  12. 欢迎评论问题,如果他们提供有价值的信息,我会改进答案。

(N.B。抱歉,无法说服解析器正确格式化,欢迎任何帮助..)