简体   繁体   English

'javax.xml.ws.Endpoint'和2种方式SSL

[英]'javax.xml.ws.Endpoint' and 2 ways SSL

I tried to deploy a web service with 2 ways SSL in java using the class 'javax.xml.ws.Endpoint'. 我尝试使用类'javax.xml.ws.Endpoint'在Java中使用2种方式部署Web服务。 My SSL setup is very restrictive. 我的SSL设置非常严格。 I have to set a specific set of options and settings. 我必须设置一组特定的选项和设置。 That's a requirement I cannot discuss. 这是我无法讨论的要求。

In order to setup SSL, I need to provide a Server Context object. 为了设置SSL,我需要提供一个Server Context对象。 After doing some search I end up using the class 'com.sun.net.httpserver.HttpsServer' (and some others related classes also in package 'com.sun'). 在做了一些搜索之后,我最终使用了类'com.sun.net.httpserver.HttpsServer'(以及其他一些相关的类也在包'com.sun'中)。 It works perfectly on a Windows JVM and on the HPUX JVM. 它在Windows JVM和HPUX JVM上运行良好。

However, I know (I should say, I believe) that classes from package 'com.sun' should not be used because they are not part of the standard runtime environment. 但是,我知道(我应该说,我相信)不应该使用包'com.sun'中的类,因为它们不是标准运行时环境的一部分。 Those classes could be moved/modified/removed without any prior notice and are JVM implementation dependant. 可以在不事先通知的情况下移动/修改/删除这些类,并且依赖于JVM实现。

My actual code is: 我的实际代码是:

private static HttpsServer createHttpsServer() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException, NoSuchProviderException {

    final String keyStoreType = "...";
    final String keyStoreFile = "...";
    final String keyStorePassword = "...";
    final String trustStoreType = "...";
    final String trustStoreFile = "...";
    final String trustStorePassword = "...";
    final String hostName = "...";
    final int portNumber = "...;
    final String sslContextName = "TLSv1.2";

    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(new FileInputStream(keyStoreFile), keyStorePassword.toCharArray());

    KeyStore trustStore = KeyStore.getInstance(trustStoreType);
    trustStore.load(new FileInputStream(trustStoreFile), trustStorePassword.toCharArray());

    KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyFactory.init(keyStore, keyStorePassword.toCharArray());

    TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustFactory.init(trustStore);

    SSLContext sslContext = SSLContext.getInstance(sslContextName);
    sslContext.init(keyFactory.getKeyManagers(), trustFactory.getTrustManagers(), getSecureRandom(pConfiguration));

    HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(hostName, portNumber), portNumber);
    HttpsConfigurator configurator = getHttpsConfigurator(pConfiguration, sslContext);
    httpsServer.setHttpsConfigurator(configurator);

    httpsServer.start();

    return httpsServer;
}

private static Endpoint publishSsl(final HttpsServer pHttpsServer, final String pPath, final Object implementationObject) {
    LOGGER.entering(LOGGER_SOURCE_CLASS, "publishSsl");

    HttpContext httpContext = pHttpsServer.createContext(pPath);
    Endpoint endPoint = Endpoint.create(implementationObject);
    endPoint.publish(httpContext);
    return endPoint;
}

private static HttpsConfigurator getHttpsConfigurator(final MyProperties pConfiguration, SSLContext pSslContext) {
    EnforcingHttpsConfigurator configurator = new EnforcingHttpsConfigurator(pSslContext);

    // Those are hidden properties to override the SSL configuration if needed.
    final String ciphers = pConfiguration.getProperty("overrideSslConfiguration.ciphers", "");
    final boolean needClientAuth = pConfiguration.getPropertyAsBoolean("overrideSslConfiguration.needClientAuth", true);
    final String protocols = pConfiguration.getProperty("overrideSslConfiguration.protocols", "");

    if (!ciphers.isEmpty()) {
        configurator.setCiphers(ciphers);
    }

    configurator.setNeedClientAuth(needClientAuth);

    if (!protocols.isEmpty()) {
        configurator.setProtocols(protocols);
    }

    return configurator;
}

public class EnforcingHttpsConfigurator extends HttpsConfigurator {
private static final Logger LOGGER = Logger.getLogger(EnforcingHttpsConfigurator.class.getCanonicalName());
private static final String LOGGER_SOURCE_CLASS = EnforcingHttpsConfigurator.class.getName();

private String mProtocols = "TLSv1.2";
private String mCiphers = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256";
private boolean mNeedClientAuth = true;

public EnforcingHttpsConfigurator(SSLContext pSslContext) {
    super(pSslContext);
}

public String getProtocols() {
    return mProtocols;
}

public void setProtocols(String pProtocols) {
    LOGGER.warning("Override SSL configuration, Set protocols '" + pProtocols + "'. This is potentially unsafe.");
    mProtocols = pProtocols;
}

public String getCiphers() {
    return mCiphers;
}

public void setCiphers(String pCiphers) {
    LOGGER.warning("Override SSL configuration, Set ciphers '" + pCiphers + "'. This is potentially unsafe.");
    mCiphers = pCiphers;
}

public boolean isNeedClientAuth() {
    return mNeedClientAuth;
}

public void setNeedClientAuth(boolean pNeedClientAuth) {
    if (!pNeedClientAuth) {
        LOGGER.warning("Override SSL configuration, no client authentication required. This is potentially unsafe.");
    }
    mNeedClientAuth = pNeedClientAuth;
}

@Override
public void configure(HttpsParameters params) {
    LOGGER.entering(LOGGER_SOURCE_CLASS, "configure");

    final SSLContext context = getSSLContext();
    final SSLParameters sslParams = context.getDefaultSSLParameters();

    // Override current values
    sslParams.setCipherSuites(mCiphers.split(","));
    sslParams.setProtocols(mProtocols.split(","));
    sslParams.setNeedClientAuth(mNeedClientAuth);

    params.setSSLParameters(sslParams);

    LOGGER.exiting(LOGGER_SOURCE_CLASS, "configure");
}

}

Question 1: Is the statement 'should not use classes in com.sun' valid? 问题1:声明'不应该使用com.sun中的类'是否有效? For the reason I explained? 我解释的原因是什么? From my search (eg What is inside com.sun package? ), I found out it seems to have a difference between package 'sun. 从我的搜索(例如什么是com.sun包里面? ),我发现它似乎与包'sun之间有区别。 ' and 'com.sun. '和'com.sun。 '. ”。 Still no definitive (documented) answer. 仍然没有明确(记录)的答案。 Please, give reference for your answer. 请为您的答案提供参考。

Question 2: If I should not use the class 'com.sun.net.httpserver.HttpsServer', what could/should I use? 问题2:如果我不使用“com.sun.net.httpserver.HttpsServer”类,我可以/应该使用什么?

NOTE: I don't want to use a container (like Tomcat, Jetty, ...). 注意:我不想使用容器(如Tomcat,Jetty,......)。 I won't explain the reason. 我不会解释原因。 That's off topic. 这不是主题。

There's no issue with using the com.sun.net package HTTP server other than it's not part of the JDK spec, it's just more code that Oracle bundle into their distribution. 使用com.sun.net包HTTP服务器没有问题,除了它不是JDK规范的一部分,它只是Oracle捆绑到其分发中的更多代码。 You wont find those classes in OpenJDK, but it's no different from say tomcat or jetty. 你不会在OpenJDK中找到这些类,但它与tomcat或jetty没有什么不同。 The issue with using sun or com.sun packages has always been that they are not part of the JDK spec, they are their code that implements various JDK components or just stuff they provide, because they are good guys/gals. 使用suncom.sun包的问题一直是它们不是JDK规范的一部分,它们是实现各种JDK组件的代码,或者只是它们提供的东西,因为它们是好人/ gals。 See this SO question and this FAQ from Oracle for details about sun. 有关sun.详细信息,请参阅Oracle的 此问题此常见问题解答 sun. and com.sun com.sun

Personally I would avoid it because there are better options. 我个人会避免它,因为有更好的选择。 You can package your Endpoint up as a WAR file and deploy to a servlet engine or use Spring Boot/Dropwizard to bundle the servlet engine into a big jar file. 您可以将Endpoint打包为WAR文件并部署到servlet引擎或使用Spring Boot / Dropwizard将servlet引擎捆绑到一个大的jar文件中。

I'd look at the servlet engines that use battle tested non blocking IO and have much better management and operational control. 我会看一下使用经过战斗测试的非阻塞IO的servlet引擎,并且具有更好的管理和操作控制。 Already mentioned are Jetty and Tomcat which are both very good, there's also JBoss Wildfly and a bunch of other commercial options (WebLogic, Websphere, probably thousands of others) 已经提到Jetty和Tomcat都非常好,还有JBoss Wildfly和一些其他商业选项(WebLogic,Websphere,可能还有数千个)

All of these will allow you to do 2-way SSL, and many will allow you to re-use your existing KeyStore and TrustStore code. 所有这些都允许您执行双向SSL,许多将允许您重用现有的KeyStoreTrustStore代码。

Spring Boot has a nice SOAP example and you will find the same approach works for many other servlet engines. Spring Boot有一个很好的SOAP示例 ,您会发现相同的方法适用于许多其他servlet引擎。

Starting JDK9 (and recent version of JDK8), there is a tool named 'jdeps' which provides the option '-jdkinternals'. 启动JDK9(以及最新版本的JDK8),有一个名为'jdeps'的工具,它提供了选项'-jdkinternals'。 Using it against my code will report nothing. 对我的代码使用它将不会报告任何内容。 This means (as per question No output with jdeps when using -jdkinternals ) 'com.sun.net.httpserver.HttpsServer' is NOT an internal class. 这意味着(根据问题,使用-jdkinternals时没有带jdeps的输出 )'com.sun.net.httpserver.HttpsServer'不是内部类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在HTTPS中使用javax.xml.ws.Endpoint - Using javax.xml.ws.Endpoint with HTTPS 不支持基于https协议的地址-javax.xml.ws.Endpoint - https protocol based address is not supported - javax.xml.ws.Endpoint 导入Javax.xml.ws.Endpoint出现错误 - import Javax.xml.ws.Endpoint got error Javax.xml.ws.Endpoint如何处理多个连接? - Javax.xml.ws.Endpoint how does it deal with multiple connections? ClassNotFoundException:javax.xml.ws.Endpoint 尽管具有正确的(?)maven 依赖项并且仅在 CLI 中 - ClassNotFoundException: javax.xml.ws.Endpoint despite having the correct(?) maven dependency and only in CLI 使用javax.xml.ws.Endpoint公开Java Web服务的局限性? - Limitations of exposing Java web services using javax.xml.ws.Endpoint? javax.xml.ws.Service通过SSL使用SOAP服务 - javax.xml.ws.Service to consume SOAP service via SSL “异常javax.xml.ws.WebServiceException:不支持的端点地址”尝试使用JAX-WS 2.1调用Web服务 - “Exception javax.xml.ws.WebServiceException: Unsupported endpoint address” trying to call web service using JAX-WS 2.1 Java WebService抛出带有无效端点接口的javax.xml.ws.WebServiceException - Java WebService throwing javax.xml.ws.WebServiceException with Invalid Endpoint Interface javax.xml.ws.WebServiceException:不是有效的端口 - javax.xml.ws.WebServiceException: is not a valid port
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM