草庐IT

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

coder 2024-03-04 原文

我尝试使用“javax.xml.ws.Endpoint”类在 Java 中部署具有 2 种 SSL 方式的 Web 服务。我的 SSL 设置非常严格。我必须设置一组特定的选项和设置。这是我无法讨论的要求。

为了设置 SSL,我需要提供一个服务器上下文对象。在做了一些搜索之后,我最终使用了“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?),我发现包“sun.”和“com.sun.”之间似乎有所不同。仍然没有明确的(记录在案的)答案。请为您的答案提供引用。

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

注意:我不想使用容器(如 Tomcat、Jetty 等)。我不会解释原因。那是题外话。

最佳答案

使用 com.sun.net 包 HTTP 服务器没有问题,除了它不是 JDK 规范的一部分,它只是 Oracle 将更多代码捆绑到他们的发行版中。你不会在 OpenJDK 中找到这些类,但它与 tomcat 或 jetty 没有什么不同。使用 suncom.sun 包的问题一直是它们不是 JDK 规范的一部分,它们是实现各种 JDK 组件的代码或只是它们的东西提供,因为他们是好人/好人。参见 this SO questionthis FAQ from Oracle有关 sun.com.sun

的详细信息

我个人会避免使用它,因为有更好的选择。您可以将端点打包为 WAR 文件并部署到 servlet 引擎或使用 Spring Boot/Dropwizard 将 servlet 引擎捆绑到一个大 jar 文件中。

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

所有这些都将允许您执行双向 SSL,并且许多将允许您重新使用现有的 KeyStoreTrustStore 代码。

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

关于java - 'javax.xml.ws.Endpoint' 和 2 种 SSL 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43761160/

有关java - 'javax.xml.ws.Endpoint' 和 2 种 SSL 方式的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  8. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  9. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  10. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

随机推荐