Skip to content
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

How to use TLS/SSL two-way authentication connections in browser? #1515

Closed
ysfscream opened this issue Jul 22, 2022 · 6 comments
Closed

How to use TLS/SSL two-way authentication connections in browser? #1515

ysfscream opened this issue Jul 22, 2022 · 6 comments

Comments

@ysfscream
Copy link
Contributor

ysfscream commented Jul 22, 2022

Hi, guys. I want to use two-way authentication when connecting using WebSocket, but when I use the client certificate, it shows that the connection has failed, so I would like to ask how to use TLS/SSL two-way authentication in the browser?

I am very sorry for the disturbance, I would be very grateful.

Currently, I am configuring the contents of the ca, cert and key files directly into options in the code, but I can't use them, unlike when using TCP connections.

const { host, port, endpoint, ...options } = this.connection
options.rejectUnauthorized = true
options.ca = certs.ca
options.cert = certs.sert
options.key = certs.key
const connectUrl = `wss://${host}:${port}${endpoint}`
this.client = mqtt.connect(connectUrl, options)

Because I tested it, it will connect fine if I don't use WebSocket.

The only error message I get is that the connection failed. I think it's an error when creating a new WebSocket client.

image

@YoDaMa

@ysfscream ysfscream changed the title How to use two-way authentication connections in browser? How to use TLS/SSL two-way authentication connections in browser? Jul 25, 2022
@MattBrittan
Copy link

"two-way authentication connections in browser" - short answer is "you can't".

Longer answer is that you can use client certificates by setting them up in your OS certificate store (or potentially some kind of smart card). When the browser connects and a client certificate is requested it will attempt to find a certificate in the store (for more info see here and here and here). So you may, potentially, be able to get this to work by manually adding the certificates to every client (but I suspect that's not a viable solution).

Unfortunately, current browsers (as far as I am aware) do not provide any way for Javascript code to specify a client certificate to be used when establishing a connection. This means there is no way for this library to do so. In the same way you can't specify a CA to use (the browser also controls that).

Note that this is a duplicate of #421 and #741

@ysfscream
Copy link
Contributor Author

@MattBrittan Thank you for your answer! it solved my doubts and I will close this issue

@afgarcia86
Copy link

Is there no way to send the certs to the backend so that the backend can still do 1 Way TLS Auth?

I would like for the server to reject my connection if I don't send a valid self signed certificate. I found a potential work around by adding a Trusted CA, Cert & Key along with an extra Self Signed Root CA. So that my server can decide if it trusts me or not. It seems to work as expected with the MQTTX tool but if I enable TLS Verify Client it rejects the connection and I am pretty sure its because the library is not including the certs I am giving it in the options.

@MattBrittan
Copy link

MattBrittan commented Mar 2, 2024

@afgarcia86 its kind of possible if you manually load the certs (how you do this would depend on the browser/os). However, its not something javascript (run by the browser) has any control over (there is nothing the library can do to help here).

@afgarcia86
Copy link

@MattBrittan do you have any context you can share that might send me down the right direction? It seems like there is a hack here that might work: #741 (comment)

@MattBrittan
Copy link

MattBrittan commented Mar 2, 2024

@afgarcia86 sorry - it's not something I've tried for some time (realistically this might work for a developer account, but the process is too complicated for most end users). It looks like that "hack" is just making an https request prior to making the wss request (this may be needed if the browser does not prompt you to load a cert when making the wss request). See something like this for instructions on loading the certs client side. Note that I don't think 1-Way auth is possible (if using TLS the browser will always verify the server cert).
A better approach might be to pass a JWT (or similar) and have the server verify that (how you would do that would vary from broker to broker; with Mosquitto mosquitto-go-auth would support this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants