【问题标题】:2-way SSL for web services on GAE (java)GAE (java) 上用于 Web 服务的 2 路 SSL
【发布时间】:2012-06-11 16:05:45
【问题描述】:

我们需要在 Google App Engine 上实现双向 SSL,我们使用 JAX-WS 将 Web 服务请求发送到要求双向 SSL 身份验证的服务器。

我们如何为传出的 Web 服务请求设置 2-way SSL?

我们知道 javax.net.ssl* 在 App Engine 环境中是被禁止的。

这是我们的代码示例:

@WebService(name="ListenerSoap", targetNamespace = "http://example.com/Listener.Wsdl")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ListenerSoap {

    @WebMethod(operationName = "Ping", action="http://example.com/Listener.Wsdl#Ping")
    public void ping();
}

@WebServiceClient(name="Listener", targetNamespace="http://example.com/Listener.Wsdl", wsdlLocation = "https://example.com/Listener.asmx?WSDL")
public class Listener extends Service
{
  public ListenerSoap getListenerSoap() {
   return super.getPort(new QName("http://example.com/Listener.Wsdl", 
                       "ListenerSoap"), ListenerSoap.class);
  }
}

以及上面代码的使用示例:

ListenerSoap soap = new Listener().getListenerSoap();
soap.ping();

我认为我们可以将 DataStore 中所需的密钥库或任何证书存储为二进制对象(尽管如何上传它们对我来说仍然很模糊)。

我们如何设置此 Web 服务使用 2-way SSL 进行身份验证所需的必要值?

感谢您的帮助

更新:

通过研究,我发现这是如何在传统服务器(具有文件系统访问权限的服务器)上完成的:

ListenerSoap soap = new Listener().getListenerSoap();
((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore", "client_cert.p12"

但是,在这种方法中,client_cert.p12 应该在文件系统上。

此外,SSLSocketFactorySSLContextKeyManagerKeyManagerFactory 都不允许在 GAE 上使用。

更新:

从 GAE SDK 版本 1.7.7 开始。现在应该可以了:

Similarly, Java developers can now use the javax.net.ssl package to make outbound SSL connections.

GAE 1.7.7 SDK Release Notes

【问题讨论】:

标签: java web-services google-app-engine ssl pki


【解决方案1】:

根据我对 SSL 授权的有限了解,您似乎在这里遗漏了一些至关重要的东西;证书。双向 SSL 要求客户端和服务器证书在您的密钥库中,可以是自签名证书(pkcs12 或 pem 文件,您可以通过 shell 使用一些命令轻松生成)或由像 Thawte 或 Verisign 这样的授权公司。 虽然我不确定这是否是您面临的问题,但最好检查一下。 (另外,我是新手,所以请不要对我的回答投反对票,只是想提出可能的选择。)

【讨论】:

  • 谢谢。我们拥有所有的密钥和证书。问题在于能够在 GAE 环境中提供证书,这在当时是不可能的,但今天看来,借助 Google 最近的白名单,这是可能的。
【解决方案2】:
ListenerSoap soap = new Listener().getListenerSoap();

希望改进

谢谢

【讨论】:

  • 是的,这甚至包含在帖子中......问题是如何让 2-way SSL 在 GAE 上工作——这项任务似乎不可行。
【解决方案3】:

我知道您可能不想听到这个消息,但是使用 SSL 的成本很高,而且对于双向通信来说是有问题的。根据您对服务器/客户端的控制程度,我更喜欢简单的双向管道,如 Web 套接字和可以简单实现 AES 的数据包协议。这实际上取决于您要解决的问题。

【讨论】:

  • 我认为 OP 正在谈论双向 授权(实际上是身份验证)。
  • 通信在两个方向上都是安全的;公钥/私钥用于交易双方用于加密的对称密钥。这个问题是关于在 both 客户端 服务器上使用证书,以对彼此进行身份验证。
  • 是的,我们需要它来进行身份验证和满足合作伙伴的软件要求。如果是我的选择,我会做简单的 SSL,这在 GAE 上是允许的。
  • 也许你可以跟随不同的拱门。如果不允许 -> 使用另一个站点进行 2 种方式 ssl(有一些 Java 提供商每月 10 美元起),并让该站点与 GAE 对话,您可以在其中验证 IP 地址。如果您无法获得 2 种方式 ssl 并且无法离开谷歌应用引擎,建议您
  • @tgkprog 刚刚看到您的评论 - 这正是我们最终采用的解决方案,在我们的内部网络上设置了一个能够处理身份验证的代理。
【解决方案4】:

听起来对通过 SSL (https://...) 的简单连接和所谓的“相互身份验证”或“公钥基础设施 (PKI)”存在混淆。您实际上可以同时做这两个或一个独立于另一个。对于后者(我认为原始问题指的是),当您向服务器发出请求时,服务器将响应您要求您提供证书以进行身份​​验证。

要回答上面的具体问题(从二进制数据加载密钥库),我认为这不太可能,因为它是 Java 运行时在您的密钥库中提取。您唯一能做的就是从数据存储中加载这些位并将其临时写入磁盘。当应用程序存在时,可选择将其删除。这是我以前做过的,效果很好。如果你这样做,我建议使用可能是可写的位置(例如System.getProperty("java.io.tmpdir"));),然后在将文件写入磁盘后,设置JVM属性(例如System.getProperties().put( "javax.net.ssl.keyStore","...");

【讨论】:

  • 另一个选项(如果您不能写入磁盘也不能使用 javax.net.ssl.*)是手动进行连接(即使用 Apache HTTP 客户端),以添加密钥库。然后,您只需定期 HTTP POST 到端点并解析响应。见:stackoverflow.com/questions/5206010/…
  • 如原帖更新中所述,由于这些软件包的黑名单,无法在 GAE 上设置 javax.net.ssl。也不可能写入任何文件磁盘。我们已经使用它在其他服务器上设置了 PKI,但 GAE 不允许这样做。
  • 知道了。我对 GAE 不是很熟悉。看起来您唯一的选择是不使用 JAX-WS 代码,而是使用像 Apache HTTPClient 这样的较低级别的东西,您可以在其中设置所有安全信息。它并不漂亮,但我使用了 Velocity 之类的东西来模板化 SOAP 消息并使用 Apache HC 将其发布到服务器。缺点是您必须手动解析响应(没有使用 JAX-WS 生成的代码获得的花哨的 POJO 映射)。
【解决方案5】:

为此,您需要 App Engine 的 Socket API。此 API 处于受信任的测试者模式,因此并非所有人都可以使用。

您可以要求访问基尔:https://docs.google.com/spreadsheet/viewform?formkey=dF9QR3pnQ2pNa0dqalViSTZoenVkcHc6MQ#gid=0

【讨论】:

    【解决方案6】:

    据我所知,不支持 2 路 SSL(从 GAE 中托管的应用程序到外部世界)。几个月前我尝试了一个示例应用程序,但很沮丧地发现 GAE 甚至不支持这个基本功能......而且文档也不清楚。当您联系网络服务时,您将无法出示客户端证书。没有地方存储它,无法访问密钥库。

    【讨论】:

    • 我还没有尝试过,但从 GAE SDK v1.7.7 开始,现在可能可以这样做,因为他们已将 javax.net.ssl 包列入白名单,现在应该让我们指定证书来自((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore"...
    【解决方案7】:

    据我所知,关于双向 SSL,您将无法与 Java EE 代码链接:双向 SSL 是一种传输层安全性:当您的客户端应用程序将尝试与服务创建安全的 HTTP 连接 (HTTPS) 时,服务器将要求提供证书,并将批准或不批准此证书。如果客户端证书被批准,则将在各方上建立安全连接,并允许他们通过此隧道交换一些消息。但是这个过程是在传输层上完成的。你的代码(在应用层)永远不会被告知这个过程。 为了建立双向 SSL,需要在应用服务器上设置 SSL 端口。

    【讨论】:

    • 这绝对不是真的。完全可以通过应用程序代码建立双向 SSL 连接,例如设置systemProps.put("javax.net.ssl.keyStore", keyStorePath);。问题是 GAE 将 java.net.ssl* 软件包列入黑名单,因此在撰写本文时,不可能在 GAE 上执行此操作。
    • 我应该承认我错了。这里是关于如何在 Java 代码中实现两种方式 SSL 的示例代码:sites.google.com/site/ssljavaguide/example-code/2-way-ssl
    • 这仍然无法在 GAE 上运行,因为所有类都被列入了 javax.net.ssl.* 包的黑名单,包括 SSLSocketSSLSocketFactory
    猜你喜欢
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多