New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SignalR not supporting self-signed certificates #4697
Comments
To get a better understanding of this problem we'd need to better understand the setup:
|
We have no control of the server and the server is working over http, just not over https. It is the Paxton Net2 access control system that just has a self signed SSL certificate. If I open the page in a web browser, I have to allow unsecure connection and then it works in the browser. I am trying to replicate this allowing of unsecure connection with jquery.signalr-2.4.3.min.js. The client "stack" is just the above code, that's the entirety of it so far and it is launched by node (v12). There doesn't seem to be much logging at all as launching the script just shows:
This error shows even if I point it to an IP that doesn't exist, so the error logging leaves a lot to be desired. Is there a way to enable verbose logging in jquery.signalr-2.4.3.min.js? - I couldn't find a way. |
So far we have some more clues. You’re running a node based process so this is the node client networking stack that is rejecting the self signed cert. Can you make a normal fetch request to this server? Lets take SignalR out of the picture. |
Yes, of course, this works fine for example: const fetch = require('node-fetch');
const WebSocket = require('ws');
const https = require('https');
const YOUR_TOKEN = 'Token';
console.log('Starting negotiation...');
async function negotiateSignalRConnection() {
const negotiateUrl = 'https://192.168.1.86:8443/signalr/negotiate';
console.log(`Negotiating at: ${negotiateUrl}`);
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_TOKEN}`,
},
agent: new https.Agent({
rejectUnauthorized: false,
}),
};
try {
const response = await fetch(negotiateUrl, options);
console.log('Negotiation response status:', response.status);
const jsonResponse = await response.json();
console.log('Negotiation response body:', jsonResponse);
return jsonResponse;
} catch (error) {
console.error('Negotiation error:', error);
throw error;
}
}
function connectToWebSocket(negotiationResponse) {
const connectionToken = encodeURIComponent(negotiationResponse.ConnectionToken);
const webSocketUrl = `wss://192.168.1.86:8443/signalr/connect?transport=webSockets&connectionToken=${connectionToken}`;
console.log(`Connecting to WebSocket at: ${webSocketUrl}`);
const ws = new WebSocket(webSocketUrl, {
handshakeTimeout: 5000,
agent: new https.Agent({
rejectUnauthorized: false,
}),
});
ws.on('open', function open() {
console.log('WebSocket Connected');
});
ws.on('message', function incoming(data) {
console.log('WebSocket Received:', data);
});
ws.on('error', function error(err) {
console.error('WebSocket Connection error:', err);
});
ws.on('close', function close() {
console.log('WebSocket Connection closed');
});
}
negotiateSignalRConnection()
.then(connectToWebSocket)
.catch(error => console.error('Failed to connect:', error)); I see this output:
I am guessing the payload I'm receiving is the SignalR? My issue is when I add jquery.signalr-2.4.3.min.js to the equation I can't find a mechanism to do something like: rejectUnauthorized: false I also cannot find a way to add better logging as it always just comes back with "Could not connect Error: Error during negotiation request.", even if I just point to a random IP that does not exist. I have tested it to work fine with http though so I suspect my issue is the self signed certificate being rejected. |
Maybe the next test should be making the request the same way signalr does it to see the differences? Since the negotiate request is failing that tells me websockets isn't the problem. the initial ajax request seems to be failing. Logging guidance for the client is here: |
This version of SignalR is using jQuery under the covers for the transport: SignalR/src/Microsoft.AspNet.SignalR.JS/jquery.signalR.transports.common.js Lines 180 to 188 in f3600c7
It seems like you are wanting to flow something here, but I'm not sure exactly what the setting is called (or if there is one). |
Is this a nodejs API or is it the browser API? EDIT: Seems like this a node API. In your signalr example I see you;re using JSDom. Doesn't that fundamentally change how networking works? When you run code using browser APIs in node, do you know how they are mapped? |
This looks relevant: https://github.com/jsdom/jsdom?tab=readme-ov-file#advanced-configuration |
Expected behavior
It should create the connection
Actual behavior
It drops the connection without any useful error, just showing:
It shows this error even if I specify a completely invalid URL too.
Steps to reproduce
I have this simple javascript code that works fine over http, but as soon as I try to make a connection to an https server with a self signed certificate, it fails with: "Could not connect Error: Error during negotiation request."
The code is:
I start the script with:
Any solution to make it work with self signed certificates? - This is not a secure application so I would be happy with a mechanism not to validate the SSL certificate.
The text was updated successfully, but these errors were encountered: