信任Java Playframework 2.2中的所有SSL证书
我试图在Play框架中调用一个web服务(具有自签名SSL证书) 使用以下功能:信任Java Playframework 2.2中的所有SSL证书,java,ssl,playframework-2.0,ssl-certificate,Java,Ssl,Playframework 2.0,Ssl Certificate,我试图在Play框架中调用一个web服务(具有自签名SSL证书) 使用以下功能: public static play.libs.F.Promise<Result> webcall() { String feedUrl = "https://10.0.1.1/client/api"; final play.libs.F.Promise<Result> resultPromise = WS.url(feedUrl).get().map(
public static play.libs.F.Promise<Result> webcall() {
String feedUrl = "https://10.0.1.1/client/api";
final play.libs.F.Promise<Result> resultPromise = WS.url(feedUrl).get().map(
new Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok("Feed title:" + response.asJson().findPath("title").toString());
}
}
);
return resultPromise;
}
如果我使用HttpsURLConnection调用该服务,则通过添加
TrustManager[] trustAllcerts = new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
}};
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
sc.init(null, trustAllcerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
// TODO Auto-generated method stub
return false;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
如何信任Play Framework中的所有自签名的/不受信任的ssl证书?尝试将以下代码添加到
conf/application.conf
文件中
ws.acceptAnyCertificate=true
如果您使用的是Promise
类,这将起作用。但如果您通过其他HttpClient调用该服务,则无法正常工作
更新:从Play Framework 2.5开始,您应该使用以下内容-
play.ws.ssl.loose.acceptAnyCertificate=true
您可以在开发环境中这样做,但决不应该在生产环境中这样做,因为这会被证明是一种安全威胁。在生产环境中,改为在密钥库中安装客户端的证书 只需在信任存储中安装您试图信任的证书即可
ws.ssl {
trustManager = {
stores = [
{ path: ${store.directory}/exampletrust.jks } # Added trust store
{ path: ${java.home}/lib/security/cacerts } # Fallback to default JSSE trust store
]
}
}
不要盲目地接受所有证书。这使您的应用程序容易受到MITM攻击
即使只是为了开发,人们也会在截止日期那天忘记删除这种代码和设置
您可能遇到的下一个问题是主机名匹配。您正在
https://10.0.1.1/
,因此您的证书应该具有此IP地址的SAN条目,而不仅仅是其CN中的该IP地址。更多细节。不要使用您在代码中设置的主机名验证程序(出于相同的原因)。请不要接受所有证书--您可以使用自定义证书的信任管理器,然后返回默认的信任存储
ws.ssl {
trustManager = {
stores = [
{ path: ${store.directory}/exampletrust.jks } # Added trust store
{ path: ${java.home}/lib/security/cacerts } # Fallback to default JSSE trust store
]
}
}
有关详细信息,请参阅。您可以尝试设置这些参数
-Dmail.smtp.ssl.trust=* -Dmail.smtp.ssl.checkserveridentity=false
启动应用程序时。以下是所有参数的列表:感谢您的宝贵建议。请不要这样做。您可以从Play TLS activator示例中生成所需的证书,然后将cacerts添加到ws.ssl中的trustManager中(请参见下面的示例)。这是危险的、安全的。您不想盲目地接受play 2.5的任何证书。您可以使用play.ws.ssl.loose.acceptAnyCertificate=true。但正如前面所说,这可能非常危险,请在使用前阅读。我对play框架不熟悉,不知道store.directory到底在哪里?打包如何与自定义信任存储一起工作?我把它放在conf中,并用路径'conf/exampletrust.jks'引用它。这会与应用程序正确打包吗?是的,很好。有关某些自定义证书的示例,请参阅。如果信任存储使用相对路径,则它将与应用程序的启动位置相对。配置中是否有一个变量可用于引用已部署应用程序的根目录,以便在不使用绝对路径的情况下部署信任存储?您可以使用HOCON替换和回退到环境变量来使用${?绝对路径}等定义绝对路径。