加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

‘javax.xml.ws.Endpoint’和2种SSL方式

发布时间:2020-12-14 05:07:05 所属栏目:Java 来源:网络整理
导读:我尝试使用类 javax.xml.ws.Endpoint在 Java中部署2种SSL方式的Web服务.我的SSL设置是非常严格的.我必须设置一组特定的选项和设置.这是我不能讨论的??要求. 为了设置SSL,我需要提供一个Server Context对象.进行一些搜索后,我最终使用类’com.sun.net.httpser
我尝试使用类 javax.xml.ws.Endpoint在 Java中部署2种SSL方式的Web服务.我的SSL设置是非常严格的.我必须设置一组特定的选项和设置.这是我不能讨论的??要求.

为了设置SSL,我需要提供一个Server Context对象.进行一些搜索后,我最终使用类’com.sun.net.httpserver.HttpsServer'(还有一些其他相关的类也在包com.sun中).它在Windows JVM和HPUX JVM上完美地工作.

但是,我知道(我应该说,我相信)从包com.sun的类不应该使用,因为它们不是标准运行时环境的一部分.这些类可以移动/修改/删除,而不需要任何事先通知,并且依赖于JVM实现.

我的实际代码是:

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");
}

}

问题1:声明“不应该使用com.sun”中的类有效吗?为什么我解释了?从我的搜索(例如What is inside com.sun package?),我发现它似乎在包“太阳”和“com.sun”之间有区别.仍然没有确定的(记录的)答案.请参考你的答案.

问题2:如果我不能使用’com.sun.net.httpserver.HttpsServer’类,可以/应该使用什么?

注意:我不想使用容器(如Tomcat,Jetty,…).我不会解释原因.这就是主题.

解决方法

使用com.sun.net软件包HTTP服务器不是JDK规范的一部分,没有问题,只是Oracle捆绑到其发行版中的更多代码.你不会在OpenJDK中找到这些类,但是与tomcat或jetty不同.使用sun或com.sun软件包的问题一直是它们不是JDK规范的一部分,它们是他们的代码,它们实现各种JDK组件,或者只是他们提供的东西,因为它们是好人/ gals.有关太阳的详细信息,请参见 this SO question和 this FAQ from Oracle.和com.sun

就个人而言,我会避开它,因为有更好的选择.您可以将您的Endpoint打包成WAR文件并部署到servlet引擎,或使用Spring Boot / Dropwizard将servlet引擎捆绑到一个大型jar文件中.

我会看看使用经过测试的非阻塞IO的servlet引擎,并具有更好的管理和操作控制.已经提到的是Jetty和Tomcat都非常好,还有JBoss Wildfly和一些其他商业选项(WebLogic,Websphere,可能还有其他几千个)

所有这些将允许您进行双向SSL,许多将允许您重新使用现有的KeyStore和TrustStore代码.

Spring Boot有一个nice SOAP example,你会发现同样的方法适用于许多其他servlet引擎.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读