Set SSLSocketFactory to JAX-WS web service call on Weblogic 12c - java

I need to call an external web service endpoint through HTTPS, using an SSL certificate. The right way should be setting a custom SSLSocketFactory using the BindingProvider, but I'm not able to get it working. To get the connection working I have to set a default SSLSocketFactory:
public void secureStoreSignedOffPdf(String filename, byte[] signedOffPdf, URL endpoint, String applicationEnvironmentId) {
final SSLSocketFactory defaultSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
final SSLSocketFactory wsSslSocketFactory = SslHelper.buildWebServiceSslSocketFactory(applicationEnvironmentId);
// TODO Fix: this should work only setting the property with BindingProvider (see below)
HttpsURLConnection.setDefaultSSLSocketFactory(wsSslSocketFactory);
final StoragePortService storagePortService = new StoragePortService();
final StoragePort storagePort = storagePortService.getStoragePortSoap11();
final BindingProvider bindingProvider = (BindingProvider) storagePort;
bindingProvider.getRequestContext()
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint.toString());
bindingProvider.getRequestContext()
.put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
final StorageRequest storageRequest = new StorageRequest();
final Document document = new Document();
document.setContent(new DataHandler(new ByteArrayDataSource(signedOffPdf, PDF_CONTENT_TYPE)));
document.setName(filename);
storageRequest.setOverwrite(true);
storageRequest.setBaseDocument(document);
final StorageResponse storageResponse = storagePort.storage(storageRequest);
HttpsURLConnection.setDefaultSSLSocketFactory(defaultSslSocketFactory);
if (!storageResponse.getReturnCode()
.equalsIgnoreCase(RESPONSE_OK)) {
throw new IllegalStateException("Web service failed with error: "
+ storageResponse.getReturnCode()
+ " - "
+ storageResponse.getReturnMessage());
}
}
If I remove this line:
bindingProvider.getRequestContext().put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
The code still works (because I'm using the HttpsURLConnection.setDefaultSSLSocketFactory method). But if in that line I put a wrong SSLSocketFactory, it fails, so it means that putting the factory attribute does something.
What I don't get is the call working without setting the default SSLSocketFactory:
HttpsURLConnection.setDefaultSSLSocketFactory(...)
FYI: I've already tried with:
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
but it doesn't do anything.

Related

Java `https.proxyHost` and `https.proxyPort` succeed then fail when using google-cloud-storage

I have some code that unit tests fine using https.proxyHost and https.proxyPort to access Google Cloud Storage Buckets on on a corporate network which needs to go via a proxy:
log.info("resolving service....");
Storage storage = StorageOptions.newBuilder()
.setCredentials(
ServiceAccountCredentials.fromStream(
new FileInputStream(fullPath)))
.build()
.getService();
log.info("resolving bucket....");
bucket = storage.get(bucketName);
Yet when I run it in a larger app that starts a lot of other internal services (e.g., RMI) the proxy settings stop working.
Running as:
java -Dhttps.proxyHost=googleapis-dev.gcp.cloud.corporate -Dhttps.proxyPort=3128 ...
When it tries to resolve a bucket with the unit tested code it hangs for ages then throws:
com.google.cloud.storage.StorageException: Error getting access token for service account: oauth2.googleapis.com
at com.google.cloud.storage.spi.v1.HttpStorageRpc.translate(HttpStorageRpc.java:231) ~[htu-gcs-plugin.jar:?]
...
Caused by: java.io.IOException: Error getting access token for service account: oauth2.googleapis.com
at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:444) ~[?:?]
at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:157) ~[?:?]
...
Caused by: java.net.UnknownHostException: oauth2.googleapis.com
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184) ~[?:1.8.0_231]
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[?:1.8.0_231]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[?:1.8.0_231]
at java.net.Socket.connect(Socket.java:606) ~[?:1.8.0_231]
at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:666) ~[?:1.8.0_231]
I can get exactly the same error without proxy settings by adding this to the top of the main method:
String hostname = "https://oauth2.googleapis.com";
HttpURLConnection con = (HttpURLConnection) new URL(hostname).openConnection();
int code = con.getResponseCode();
System.out.println("> https://oauth2.googleapis.com returned: "+code);
Yet if the proxy settings are pass that runs fine then later throws the java.net.UnknownHostException as through the proxy settings are cleared.
To make things a bit more complex a custom URLClassLoader is used to load the code in question. Yet I have made a standalone app that uses the classloader and runs the code fine with the proxy settings passed as normal.
So it appears that something in the larger app is messing with the proxy system settings. Searching the codebase I can see no trace of that.
I have looked at https://googleapis.github.io/google-http-java-client/http-transport.html to see if there is way to plugin in a transport that has a proxy but cannot find a clear example.
Is there a way to coerce the use of a proxy when using google-cloud-storage?
To explicitly force a proxy to not rely upon the standard java System properties add the client libraries:
<!-- https://mvnrepository.com/artifact/com.google.http-client/google-http-client-apache-v2 -->
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-apache-v2</artifactId>
<version>1.37.0</version>
</dependency>
Then you can create a custom HttpTransportFactory with something like:
public class ProxyAwareTransportFactory implements HttpTransportFactory {
public static SSLContext trustAllSSLContext() throws Exception {
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
return sslContext;
}
#Override
public HttpTransport create() {
InetSocketAddress socketAddress = new InetSocketAddress(this.host,this.port);
Proxy proxy = new Proxy(Proxy.Type.HTTP, socketAddress);
try {
return new NetHttpTransport.Builder()
.setProxy(proxy)
.setConnectionFactory(new DefaultConnectionFactory(proxy) )
.setSslSocketFactory(trustAllSSLContext().getSocketFactory())
.setHostnameVerifier(new DefaultHostnameVerifier())
.build();
} catch (Exception e) {
final String msg = "Could not build HttpTransport due to; " + e.getMessage();
log.error(msg, e);
throw new RuntimeException(e);
}
}
}
You can then use it using something like:
StorageOptions.Builder builder = StorageOptions.newBuilder();
if( useProxy ) {
HttpTransportFactory httpTransportFactory = new ProxyAwareTransportFactory(proxyHost, proxyPort);
HttpTransportOptions options = HttpTransportOptions.newBuilder().setHttpTransportFactory(httpTransportFactory).build();
builder.setTransportOptions(options);
}
Storage storage = builder
.setCredentials(
ServiceAccountCredentials.fromStream(
new FileInputStream(fullPath)))
.build()
.getService();

X509 Certificates are not coming in incoming client request after Jetty Upgrade to 9.4.19.v20190610

I'm not getting the X509 Certificates in incoming client request after Jetty Upgrade to
9.4.19.v20190610
certifcates = (X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
Here the certificates are null. Though they were coming in Jetty version
9.4.11.v20180605
My Client Program:
private static String loginWithCertificate(String aEndPointURL) {
String line = "";
try {
final String CERT_ALIAS = "employee1";
String CERT_PASSWORD = "changeit";
KeyStore identityKeyStore = KeyStore.getInstance("jks");
FileInputStream identityKeyStoreFile = new FileInputStream(new File(ResourceUtils.getFile("./stores/client1.jks").getAbsolutePath()));
identityKeyStore.load(identityKeyStoreFile, CERT_PASSWORD.toCharArray());
KeyStore trustKeyStore = KeyStore.getInstance("jks");
FileInputStream trustKeyStoreFile = new FileInputStream(new File(ResourceUtils.getFile("./stores/truststore1.jks").getAbsolutePath()));
trustKeyStore.load(trustKeyStoreFile, CERT_PASSWORD.toCharArray());
SSLContext sslContext = SSLContexts.custom()
// load identity keystore
.loadKeyMaterial(identityKeyStore, CERT_PASSWORD.toCharArray(), new PrivateKeyStrategy() {
#Override
public String chooseAlias(Map<String, PrivateKeyDetails> aliases, Socket socket) {
return CERT_ALIAS;
}
})
// load trust keystore
.loadTrustMaterial(trustKeyStore, null).build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" }, null, SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
HttpPost req = new HttpPost(aEndPointURL);
StringEntity entity = new StringEntity(
"{\"ipAddress\" : \"172.20.186.74\", \"port\" : 1363, \"protocol\" : \"tls1.2\"}");
req.setHeader("Content-type", "application/json");
req.setHeader("X-XSRF-TOKEN", "Y2hlY2tpdA==");
req.setHeader("CertificateAuthentication", "true");
req.setEntity(entity);
HttpResponse response = client.execute(req);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
} catch (Exception ex) {
System.out.println("Exception : " + ex);
ex.printStackTrace();
}
return line;
}
My SSL Connector at Server:
public EmbeddedServletContainerFactory customizeJetty() {
JettyEmbeddedServletContainerFactory container = new JettyEmbeddedServletContainerFactory();
container.addServerCustomizers(new JettyServerCustomizer() {
#Override
public void customize(Server server) {
// HTTP
try (ServerConnector connector = new ServerConnector(server);) {
validateHttpPort(httpPort, securedPort);
connector.setPort(Integer.parseInt(httpPort));
// HTTPS
SslContextFactory sslContextFactory = new SslContextFactory();
URL urlKeyStore = null;
Path keyStoreFilePath = null;
File keyStoreFile = null;
// Appscan Vulnerability - Should not use Hardcoded paths using File Separator.
// We should use Path API to read the files.
keyStoreFilePath = Paths.get("WebServices", "src", "main", "resources");
keyStoreFile = Paths.get(keyStoreFilePath.toString(), keyStoreName).toFile();
if (!keyStoreFile.exists()) {
keyStoreFilePath = fetchPathForKeyStore();
keyStoreFile = keyStoreFilePath.toFile();
}
urlKeyStore = fetchKeyStoreUrl(keyStoreFile);
validateUrlKeyStore(urlKeyStore);
sslContextFactory.setKeyStoreResource(Resource.newResource(urlKeyStore));
// Getting Credentials from hidden file
String encodedProperty = MFTUtils.fetchCredentialForKeyStore();
validateEncodedProperty(encodedProperty);
StringTokenizer tokenizer = new StringTokenizer(encodedProperty,
MFTConstants.HTTP_CREDENTIAL_DELIMITER); // constant
validateTokens(tokenizer);
String encodedCredential = tokenizer.nextToken();
String credentialKey = tokenizer.nextToken();
String credential = AESEncryptionDecryption.decrypt(encodedCredential, credentialKey);
// null checking credentials
validateCredential(credential, credentialKey);
sslContextFactory.setKeyStorePassword(credential);
sslContextFactory.setExcludeCipherSuites(
"SSL_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
sslContextFactory.setExcludeProtocols("");
HttpConfiguration https = new HttpConfiguration();
https.addCustomizer(new SecureRequestCustomizer());
if (System.getProperty(MFTConstants.SERVER_SSL_ENABLED).equalsIgnoreCase(MFTConstants.TRUE)) {
UtilLogger.debug(logger, "HTTPS is enabled.");
try (ServerConnector sslConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, MFTConstants.HTTP_PROTOCOL),
new HttpConnectionFactory(https));) {
sslConnector.setPort(Integer.parseInt(securedPort));
server.setConnectors(new Connector[] { connector, sslConnector });
}
} else {
UtilLogger.debug(logger, "HTTPS is disabled. Application will run over HTTP only.");
try (ServerConnector sslConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, MFTConstants.HTTP_PROTOCOL));) {
server.setConnectors(new Connector[] { connector });
}
}
}
}
I am trying with Self Signed Certificates.
Update
I'm using jks keystore. i.e. Certificates without key.
:
Any Help would be highly appreciated.
Looking closer at your server side SslContextFactory usage, with an eye on what you are actually using (stripping away to only show SslContextFactory usage)
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStoreResource(Resource.newResource(urlKeyStore));
sslContextFactory.setKeyStorePassword(credential);
sslContextFactory.setExcludeCipherSuites(
"SSL_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
sslContextFactory.setExcludeProtocols("");
A few things stand out.
First, since you are a server, you should use the server version ...
SslContextFactory sslContextFactory = new SslContextFactory.Server();
Next, your use of .setExcludedCipherSuites() is incomplete and introduces vulnerabilties.
Remove (or comment out) that entire line.
Use the defaults that SslContextFactory offers you.
With that line, it's possible to use no-certificate, and no-encryption, configurations for TLS/SSL.
Also, your use of setExcludedProtocols("") is bad. It's setting a single blank protocol to be excluded. This is bad, as you are exposing yourself to all manner of SSL vulnerabilities (let alone TLS vulnerabilities)
Remove (or comment out) that entire line also.
Use the defaults that SslContextFactory offers you.
With that line, it's possible to use no-protocol (which means no-encryption) configurations for TLS/SSL.
There's a myriad of warning logs produced with those 2 above configurations, you should strive to have a configuration that has no warnings.
For the two issues above, you might learn something from the name of the cipher suite that was used in your connection.
String cipherSuiteName =
(String) HttpServletRequest.getAttribute("javax.servlet.request.cipher_suite");
You can even obtain the javax.net.ssl.SSLSession used in the connection.
SslSession sslSession =
(SslSession) HttpServletRequest.getAttribute(
"org.eclipse.jetty.servlet.request.ssl_session");
System.out.println("protocol is " + sslSession.getProtocol());
System.out.println("cipher suite is " + sslSession.getCipherSuite());
System.out.println("peer certs is " + sslSession.getPeerCertificates());
Finally, your code has no indication that you even want client certificates from that configuration.
Have you forgotten one of ...
sslContextFactory.setNeedClientAuth​(true);
sslContextFactory.setWantClientAuth​(true);
Or are you really not wanting client certificates?

T3 client with custom SSLSocketFactory

I have my T3 client code like this:
private InitialContext initContext() {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, context.providerURL);
for (Map.Entry<String, String> entry : getEnvironmentProperties().entrySet()) {
p.put(entry.getKey(), entry.getValue());
}
InitialContext res = null;
try {
res = new InitialContext(p);
} catch (NamingException e) {
e.printStackTrace();
}
return res;
}
My t3 client deployed on Tomcat (uses wlthint3client-12.1.3.jar) and trying to lookup remote bean of external system which deployed on Weblogic.
However when I trying to perform new InitialContext(p) I receive SSLHandshake exception, because it gets standart SSLSocketFactory with standart SSLConext and standart java trust store.
My question - is there any way to give to InitialContext some property which will override SSLSocketFacory. My aim is to populate my cutom trust store to this t3 client.
Changing standart trust store like this
System.setProperty("javax.net.ssl.trustStore", "pathToTrustStore");
works fine, however in case if my t3 client is used to communicate with 2 different external systems, it might be a problem in doing so.
Is there some property that I can populate?
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
**p.put("CUSTOM SSL SOCKET FACTORY, "MY CLASS");**
Problem was solved by adding few parameters on application side
export JAVA_OPTS ="$JAVA_OPTS -Djavax.net.ssl.trustStore=path/truststore.jks"
export JAVA_OPTS ="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=changeIT"

'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’. My SSL setup is very restrictive. 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. 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’). It works perfectly on a Windows JVM and on the 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. Those classes could be moved/modified/removed without any prior notice and are JVM implementation dependant.
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? For the reason I explained? From my search (e.g. What is inside com.sun package?), I found out it seems to have a difference between package ‘sun.’ and ‘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?
NOTE: I don't want to use a container (like 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. You wont find those classes in OpenJDK, but it's no different from say tomcat or 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. See this SO question and this FAQ from Oracle for details about sun. and 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.
I'd look at the servlet engines that use battle tested non blocking IO and have much better management and operational control. 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)
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.
Spring Boot has a nice SOAP example and you will find the same approach works for many other servlet engines.
Starting JDK9 (and recent version of JDK8), there is a tool named 'jdeps' which provides the option '-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.

Akka HTTP server with SSL support in Java - How to create configuration?

I am trying to create an Akka HTTP server, which will support SSL.
I am aware of this question for scala Akka HTTP 2.0 to use SSL (HTTPS) and I am trying to work it into Java code but I am getting lost.
The DSL akka.http.javadsl.Http class is different for Java and requires akka.actor.ExtendedActorSystem, when I try to create an instance for it I am required to create an application configuration with the com.typesafe.config.Config class, which I can't figure out how to instantiate and what to put in it.
Is there any simpler way? Or any classes I can use to create all the required configurations?
This is a snippet of the code:
// boot up server using the route as defined below
final ActorSystem system = ActorSystem.create();
final ActorMaterializer materializer = ActorMaterializer.create(system);
// Run the server bound to the local machine IP
String hostAddress = InetAddress.getLocalHost().getHostAddress();
// No implementation here?????
Config applicationConfig = new Config() {
}
ExtendedActorSystem extendedActorSystem = new ActorSystemImpl("HttpProxy", applicationConfig, ClassLoader.getSystemClassLoader(), Option.empty());
// todo: missing handler, settings, httpsContext and log
Flow<HttpRequest, HttpResponse, ?> handler;
ServerSettings settings;
akka.japi.Option<HttpsContext> httpsContext;
LoggingAdapter log;
new Http(extendedActorSystem).bindAndHandle(handler, hostAddress, PORT, settings, httpsContext, log, materializer);
System.out.println("Starting server on " + hostAddress + ":" + PORT);
// The server would stop if carriage return is entered in the system cosole
System.out.println("Type RETURN to exit");
System.in.read();
system.shutdown();
It supposed to be something like this:
// boot up server using the route as defined below
// Run the server bound to the local machine IP
String hostAddress = InetAddress.getLocalHost().getHostAddress();
// No implementation here?????
Config applicationConfig = ConfigFactory.load();
ActorSystem system = ActorSystem.create("HttpProxy", applicationConfig);
final ActorMaterializer materializer = ActorMaterializer.create(system);
// todo: missing handler, settings, httpsContext and log
Flow<HttpRequest, HttpResponse, ?> handler;
ServerSettings settings;
akka.japi.Option<HttpsContext> httpsContext;
LoggingAdapter log;
Http.get(system).bindAndHandle(handler, hostAddress, 9000, settings, httpsContext, log, materializer);
System.out.println("Starting server on " + hostAddress + ":" + 9000);

Categories