Trying to connect websocket to a client endpoint that is secure throws error: XNIO000100: 'https' URL scheme chosen but no SSL provider given - ssl

I'm trying to create a websocket in java that listens to a local application on the endpoint f.ex. "wss://localhost.localapp.com:8080/".
The application do send through that websocket information about what is happening.
When I run the web-application and it tries to connect to the secure websocket it throws this error:
XNIO000100: 'https' URL scheme chosen but no SSL provider given
Here is my code for connecting to the client endpoint:
#ClientEndpoint
public class ClientEndpoint {
private Logger logger = Logger.getLogger(getClass().getName());
public ClientEndpoint() {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
try {
container.connectToServer(this, new URI("wss://localhost.localapp.com:8080/"));
} catch (DeploymentException | URISyntaxException | InterruptedException | IOException e) {
System.out.println("Connection error occured!: " + e);
}
}
#OnOpen
public void onOpen(Session session) {
this.logger.info("New websocket session opened: " + session.getId());
}
#OnClose
public void onClose(Session session) {
this.logger.info("Websoket session closed: " + session.getId());
}
#OnMessage
public void onMessage(Session session, String message) throws IOException, EncodeException {
this.logger.info("Message recieved: " + message);
}
#OnError
public void error(Session session, Throwable t) {
t.printStackTrace();
}
}
So the errors happends on this code line:
container.connectToServer(this, new URI("wss://localhost.localapp.com:8080/"));
And the stack trace output this:
ERROR localhost jboss7.1 [RunnerReadFacade] Application was stopped due to exception. Transaction is rollbacked.: java.lang.IllegalArgumentException: XNIO000100: 'https' URL scheme chosen but no SSL provider given
at org.xnio.http.HttpUpgrade$HttpUpgradeState.doUpgrade(HttpUpgrade.java:253)
at org.xnio.http.HttpUpgrade$HttpUpgradeState.access$100(HttpUpgrade.java:165)
at org.xnio.http.HttpUpgrade.performUpgrade(HttpUpgrade.java:129)
at io.undertow.websockets.client.WebSocketClient$ConnectionBuilder.connectImpl(WebSocketClient.java:323)
at io.undertow.websockets.client.WebSocketClient$ConnectionBuilder.connect(WebSocketClient.java:211)
at io.undertow.websockets.jsr.ServerWebSocketContainer.connectToServerInternal(ServerWebSocketContainer.java:463)
at io.undertow.websockets.jsr.ServerWebSocketContainer.connectToServerInternal(ServerWebSocketContainer.java:457)
at io.undertow.websockets.jsr.ServerWebSocketContainer.connectToServer(ServerWebSocketContainer.java:211)
How should I solve this?
With JavaScript I do not need a SSL provider and can simply create the connection with the websocket just by running:
websocket = new WebSocket("wss://localhost.localapp.com:8080/");
Why does the error only occure to Java?
UPDATE:
This probably cannot be done because the application is on your local computer and the server is not local.
But could this be done if you would use a local server?

You can either switch to Programmatic Client Endpoint or define Thread local SSL Context. See details at https://issues.jboss.org/browse/THORN-2131 (wsstest-master.zip includes demo app). 'Implement io.undertow.websockets.jsr.WebsocketClientSslProvider and add a META-INF/services entry' didn't work for me.

Related

Connecting to Amazon ActiveMQ with username & password

I'm trying to connect to ActiveMQ Amazon broker via SSL. My application is written in C#.
Previously, I connected via TCP to localhost ActiveMQ broker, which worked:
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using Apache.NMS.ActiveMQ.Commands;
void Connect()
{
String brokerUri = "activemq:tcp://" + host + ":" + port + "? transport.useLogging=true&wireFormat.maxInactivityDuration=0&userName=myUsername&password=myPassword";
NMSConnectionFactory factory = new NMSConnectionFactory(brokerUri);
IConnection connection = factory.CreateConnection();
connection.Start();
}
To connect to ActiveMQ Amazon broker via SSL, I have modified the code in the following way:
void Connect()
{
String brokerUri = "ssl://" + host + ":" + port + "? transport.useLogging=true&wireFormat.maxInactivityDuration=0&userName=myUsername&password=myPassword";
SslTransportFactory transportFactory = new SslTransportFactory();
Uri uri = new Uri(brokerUri);
ITransport transport = transportFactory.CreateTransport(uri);
transport.Command = Command;
transport.Exception = Exception;
transport.Start();
ConnectionFactory factory = new ConnectionFactory(brokerUri);
IConnection connection = factory.CreateConnection();
Connection con = (Connection)connection;
con.ITransport = transport;
con.Start(); => Here the exception is thrown: User name [null] or password is invalid.
}
private void Exception(ITransport sender, Exception command)
{
}
private void Command(ITransport sender, Command command)
{
}
However, upon starting the connection, User name [null] or password is invalid. Exception is thrown.
Please advise.
You're currently passing user credentials via the URI. However, I don't see any reference to username or password in the URI reference documentation. Also, the fact that the exception indicates the user name is null indicates the user credentials in your URI are simply being ignored.
Instead you should pass the user credentials in the CreateConnection method as documented here, e.g.:
IConnection connection = factory.CreateConnection("myUsername", "myPassword");

How to catch error when message have been sent from JMS

I am sending an message through my standalone application that uses EJB MDB to communicate to my other application server that is running on JBOSS server.My application server is connected to a MSSQL server. In certain scenario, connection to the database is lost on application server side and we get following error -
Connection is reset.
Later , when i try to send message i don't get any error at my standalone EJB MDB logs and the process just stops executing.I get error log on application server side logs but same logs don't get propagated to my EJB MDB error logs.
As per my understanding, when db connection is lost all the ejb bean present in jboss container get nullified too.(I could be wrong here, i am new to EJB).
I tried implementing below code in my code that use to send message -
QueueConnection qcon = null;
#PostConstruct
public void initialize() {
System.out.println("In PostConstruct");
try {
qcon = qconFactory.createQueueConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
#PreDestroy
public void releaseResources() {
System.out.println("In PreDestroy");
try {
if(qcon != null)
{
qcon.close();
}
if(qcon== null){
throw new Exception(" new exception occured.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
I was in a impression that Queueconnection object will be nullified, when our db connection have been lost(as we are creating bean and making connection for message). But it doesn't seem to work.
I did found a way to call back my application after sending message. I used a separate temporary queue and used setJMSReplyTo method to set the reply destination. More info could be obtained from this
link. Hope this helps others.

Add Proxy to restlet ClientRessource

I am trying to add proxy settings to a Java Swing client app, which connects and gets data over https from an external server. However the ClientResource (restlet:2.4.0) ignores all efforts with parameters and connects directly to the url? If the syntax is correct, what are the correct parameters?
Further, how can I use system proxy settings?
private static ClientResource getClientResource(String url) {
ClientResource clientResource = null;
try {
// test
Client client = new Client(new Context(), Protocol.HTTPS);
client.getContext().getParameters().add("https.proxyHost", "PROXY_IP");
client.getContext().getParameters().add("https.proxyPort", "PROXY_PORT");
clientResource = new ClientResource(url);
// test
clientResource.setNext(client);
} catch (Exception e) {
e.printStackTrace();
}
return clientResource;
}
private static Response sendGetRequest(String url) {
ClientResource resource = getClientResource(BASE_URL + url);
try {
resource.get();
} catch (ResourceException e){
e.printStackStrace();
return null;
}
return getResponse();
}
EDIT added compiles:
compile 'org.restlet.jse:org.restlet:2.3.12'
compile 'org.restlet.jse:org.restlet.ext.jackson:2.3.12'
// switch to Apache Http Client, enable proxy'
compile 'org.restlet.jse:org.restlet.ext.httpclient:2.3.12'
// httpClient for Class Definitions
compile 'org.apache.httpcomponents:httpclient:4.3'
CURRENT EXCEPTION:
Starting the Apache HTTP client
An error occurred during the communication with the remote HTTP server.
org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:867)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at org.restlet.ext.httpclient.internal.HttpMethodCall.sendRequest(HttpMethodCall.java:339)
at org.restlet.engine.adapter.ClientAdapter.commit(ClientAdapter.java:105)
at org.restlet.engine.adapter.HttpClientHelper.handle(HttpClientHelper.java:119)
at org.restlet.Client.handle(Client.java:153)
I think this is only supported with the httpClient extension, that relies on the Apache HTTP client library (maven artifact id: org.restlet.ext.httpclient).
You can then either use the system environment properties: http.proxyHost and http.proxyPort, or set these parameters on the client instance (as you did, but names are distinct and documented here ).
Client client = new Client(new Context(), Protocol.HTTPS);
client.getContext().getParameters().add("proxyHost", "PROXY_IP");
client.getContext().getParameters().add("proxyPort", "PROXY_PORT");

Photon Secure WebSocket Connection In Unity WebGL

I'm having trouble when I try to connect my local Photon Server with Unity3D WebGL Build, using secure websocket connection. I can establish the connection with websockets (not the secure one) and any other environment other than WebGL builds (Even in Unity's play mode with WebGL configuration, it just won't work when I get a build). I'm guessing that the problem is related with my certificate but I'm not entirely sure. I tried self-signed one, and a real one.
Here is the error:
WebSocket connection to 'wss://localhost:19091' failed: Error in
connection establishment: net::ERR_INSECURE_RESPONSE
I already tried 127.0.0.1 instead of localhost, tried to change the port.
I got my socket code from Photon's website, link is here:
https://www.photonengine.com/sdks#onpremiseunity3d
My Client code(uses Photon's SocketWebTcp class) is like this:
using ExitGames.Client.Photon;
using UnityEngine;
public class HiveClient : IPhotonPeerListener
{
public PhotonPeer PhotonClient { get; set; }
public HiveClient() { }
public void Connect()
{
this.PhotonClient = new PhotonPeer(this, ConnectionProtocol.WebSocketSecure);
this.PhotonClient.SocketImplementationConfig.Add(ConnectionProtocol.WebSocketSecure, typeof(SocketWebTcp));
this.PhotonClient.Connect("wss://localhost:19091", "Hive");
}
public void DebugReturn(DebugLevel level, string message)
{
Debug.Log("DebugReturn: " + level.ToString() + " Message: " + message);
}
public void OnEvent(EventData eventData)
{
Debug.Log("OnEvent: " + eventData.Code);
}
public void OnOperationResponse(OperationResponse operationResponse)
{
Debug.Log("OnOperationResponse: " + operationResponse.DebugMessage);
}
public void OnStatusChanged(StatusCode statusCode)
{
Debug.Log("OnStatusChanged: " + statusCode.ToString());
}}
Here is app's websocket listener in photon server config:
<WebSocketListeners>
<WebSocketListener IPAddress="0.0.0.0" Port="19091" DisableNagle="true" InactivityTimeout="10000" Secure = "true" StoreName = "MY" CertificateName = "DESKTOP-PQ845BC" UseMachineStore = "true">
</WebSocketListener>
</WebSocketListeners>
Lastly, here is my self-signed certificate:
Thank you.
Solved this, It seems certificates doesn't work with ip adresses like 127.0.0.1. Certificate expects some address (like xxx.photon.com)
As a temporary solution, one can send a https request to defined ip and insert the ip chrome's allowed ips. This temp solution relates to this answer:
https://stackoverflow.com/a/43493521/3013806

Cross domain policy file over net.tcp for WCF servicehost and Silverlight 5

I have a locally hosted WCF service and a silverlight 5 app that communicates with it. By default silverlight tries to obtain the cross domain policy file over HTTP when making calls to the WCF service. I need to change this so that the policy file is served over net.tcp port 943 instead.
I have setup a local tcp listener that serves up the policy file over port 943 and i have followed this technique whereby i make a dummy socket connection in order to obtain the policy file over tcp as it is only retrieved once per application lifetime. The tcp server is being hit as expected and i am getting SocketError property value as Success (though i must note, the first time i hit the tcp server after starting the listener, the result is always access denied).
From what i can tell, the policy file is either invalid as the silverlight application as still unable to connect or the above mentioned technique does not work with silverlight 5.
What i would like to know is if what i am doing is possible & im doing it correctly, otherwise if there is an alternative means to have the policy file successfully downloaded over tcp and removing the need for retrieving it over HTTP.
Thanks
I wrote a long post about hosting silverlight in WPF - and using WCF with a http listener here:
How can I host a Silverlight 4 application in a WPF 4 application?
Now while not directly answering your question, it does show how to create a http version of the policy file.
I have also written something that serves up a policy listener over port 943, but I can't find where I posted the source - so I'll keep digging. As far as I remember though, silverlight does a cascade find of the policy file, if it doesn't get a connection on port 80, it'll then look on port 943.
I hope this is of some help somewhere.
Ok, here is the policy listener I had for net.TCP transport i.e. not HTTP based. I presume you have sorted this by now, sorry for the delay. It may well be of use to someone else now.
I was looking for the MS thing that said they cascade from HTTP to TCP, however, I can't, and therefore have to assume it was bunk and then changed.
Either way, if you call using a net.TCP service, and want a listener for it, this code should help:
#region "Policy Listener"
// This is a simple policy listener
// that provides the cross domain policy file for silverlight applications
// this provides them with a network access policy
public class SocketPolicyListener
{
private TcpListener listener = null;
private TcpClient Client = null;
byte[] Data;
private NetworkStream netStream = null;
private string listenaddress = "";
// This could be read from a file on the disk, but for now, this gives the silverlight application
// the ability to access any domain, and all the silverlight ports 4502-4534
string policyfile = "<?xml version='1.0' encoding='utf-8'?><access-policy><cross-domain-access><policy><allow-from><domain uri='*' /></allow-from><grant-to><socket-resource port='4502-4534' protocol='tcp' /></grant-to></policy></cross-domain-access></access-policy>";
// the request that we're expecting from the client
private string _policyRequestString = "<policy-file-request/>";
// Listen for our clients to connect
public void Listen(string ListenIPAddress)
{
listenaddress = ListenIPAddress;
if (listener == null)
{
listener = new TcpListener(IPAddress.Parse(ListenIPAddress), 943);
// Try and stop our clients from lingering, keeping the socket open:
LingerOption lo = new LingerOption(true, 1);
listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger,lo);
}
listener.Start();
WaitForClientConnect();
}
private void WaitForClientConnect()
{
listener.BeginAcceptTcpClient(new AsyncCallback(OnClientConnected), listener);
}
public void StopPolicyListener()
{
if (Client.Connected)
{
// Should never reach this point, as clients
// are closed if they request the policy
// only clients that open the connection and
// do not submit a policy request will remain unclosed
Client.Close();
}
listener.Stop();
}
public void RestartPolicyListener()
{
listener.Start();
}
// When a client connects:
private void OnClientConnected(IAsyncResult ar)
{
if (ar.IsCompleted)
{
// Get the listener that handles the client request.
TcpListener listener = (TcpListener)ar.AsyncState;
// End the operation and display the received data on
// the console.
Client = listener.EndAcceptTcpClient(ar);
// Try and stop our clients from lingering, keeping the socket open:
LingerOption lo = new LingerOption(true, 1);
Client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
// Set our receive callback
Data = new byte[1024];
netStream = Client.GetStream();
netStream.BeginRead(Data, 0, 1024, ReceiveMessage, null);
}
WaitForClientConnect();
}
// Read from clients.
public void ReceiveMessage(IAsyncResult ar)
{
int bufferLength;
try
{
bufferLength = Client.GetStream().EndRead(ar);
// Receive the message from client side.
string messageReceived = Encoding.ASCII.GetString(Data, 0, bufferLength);
if (messageReceived == _policyRequestString)
{
// Send our policy file, as it's been requested
SendMessage(policyfile);
// Have to close the connection or the
// silverlight client will wait around.
Client.Close();
}
else
{
// Continue reading from client.
Client.GetStream().BeginRead(Data, 0, Data.Length, ReceiveMessage, null);
}
}
catch (Exception ex)
{
throw new Exception(Client.Client.RemoteEndPoint.ToString() + " is disconnected.");
}
}
// Send the message.
public void SendMessage(string message)
{
try
{
byte[] bytesToSend = System.Text.Encoding.ASCII.GetBytes(message);
//Client.Client.Send(bytesToSend,SocketFlags.None);
Client.GetStream().Write(bytesToSend,0, bytesToSend.Length);
Client.GetStream().Flush();
}
catch (Exception ex)
{
throw ex;
}
}
}
#endregion