Comments (5)
Hi @snej, currently the authentication is called before inheritClientSession:
Lines 443 to 457 in 5966c7f
Although with static username, it is reasonable to assume username should remain the same to inherit a clientID, but I have seen use-case where username is dynamic, like using JWT.
Given MQTT spec (section 5.4.2) leaves what should be checked (username, IP, etc) to the authentication mechanisms, perhaps implementing custom OnConnectAuthenticate is the better route if the requirement is to associate username with clientID?
from server.
currently the authentication is called before inheritClientSession
Yes, but this issue isn't related to client authentication, rather to channel authorization.
For example, if I log in with my valid username and password, but use a session ID that matches your last session, then I will end up with all of your channel subscriptions, whether or not I was supposed to be able to access those channels.
perhaps implementing custom OnConnectAuthenticate is the better route if the requirement is to associate username with clientID?
That seems reasonable. The Auth Ledger hook should be updated to do this, then, since I assume that's what most developers will use.
The check in the hook would probably look something like this?
func (h *myAuthHook) OnConnectAuthenticate(cl *mochi.Client, pk packets.Packet) bool {
existing, _ := h.server.Clients.Get(pk.Connect.ClientIdentifier)
if existing != nil && !slices.Equal(existing.Properties.Username, cl.Properties.Username) {
return false
}
...
}
This does have the problem that the error sent to the client will be ErrBadUsernameOrPassword, which isn't accurate; probably ErrClientIdentifierNotValid would be better. Is there any way to customize the error returned to the client?
from server.
Yes, but this issue isn't related to client authentication, rather to channel authorization.
For example, if I log in with my valid username and password, but use a session ID that matches your last session, then I will end up with all of your channel subscriptions, whether or not I was supposed to be able to access those channels.
Just to ensure we're on the same page, session ID means the client ID the client used to connect? If so, then the use-case you described for the complete authentication should includes clientID/username/password. I assume that username/password should always be associated with a clientID (not only on inheriting a session)
Value | Hex | Reason Code name | Description |
---|---|---|---|
133 | 0x85 | Client Identifier not valid | The Client Identifier is a valid string but is not allowed by the Server. |
135 | 0x87 | Not authorized | The Client is not authorized to connect. |
Value | Return Code Response | Description |
---|---|---|
2 | 0x02 Connection Refused, identifier rejected | The Client identifier is correct UTF-8 but not allowed by the Server |
5 | 0x05 Connection Refused, not authorized | The Client is not authorized to connect |
perhaps implementing custom OnConnectAuthenticate is the better route if the requirement is to associate username with clientID?
That seems reasonable. The Auth Ledger hook should be updated to do this, then, since I assume that's what most developers will use.
There are 2 general use-cases of mochi-mqtt:
- embedded MQTT server, generally do not use auth ledger and already use custom authentications.
- packaged solution, as mochi indicated previously, the auth ledger was meant to be a simple hook. However, more and more people are using this with different needs, perhaps it's time to revisit and redesign this?
The check in the hook would probably look something like this?
func (h *myAuthHook) OnConnectAuthenticate(cl *mochi.Client, pk packets.Packet) bool { existing, _ := h.server.Clients.Get(pk.Connect.ClientIdentifier) if existing != nil && !slices.Equal(existing.Properties.Username, cl.Properties.Username) { return false } ... }This does have the problem that the error sent to the client will be ErrBadUsernameOrPassword, which isn't accurate; probably ErrClientIdentifierNotValid would be better. Is there any way to customize the error returned to the client?
Yes, currently OnConnectAuthenticate only returns a bool. We can either change the hardcoded return code to something generic like packets.ErrNotAuthorized
:
Lines 443 to 450 in 5966c7f
or change the signature of OnConnectAuthenticate. Thoughts @mochi-co?
from server.
@snej Consider a scenario where I want all devices to log in using a single username and password, but each device is identified by a different ClientID. I think the association between username and clientID should be managed and allocated by the users themselves through hooks for better suitability.
from server.
I'm fine having the Server struct not enforce matching usernames; I'll close this PR. But it would be good if the OnConnectAuthenticate
hook could specify a different error code -- otherwise a client accidentally using someone else's client ID would be told its login is incorrect, which could be very confusing. I'll create a new PR for that.
from server.
Related Issues (20)
- Hi, what is the simplest way to make messages can be restored when server cut off? HOT 5
- [badgerdb] vlog growing unbounded - consider adding GC and exposing options HOT 6
- The badge still getting vlog file keep growing infirnity HOT 7
- How to send topics posted by specific users only to specific subscribed users? HOT 11
- Does peddle perssistant released? HOT 5
- MQTTX cannot use Topic Alias. MQTT5.0 主题别名发送卡住,无法发布主题别名的消息 HOT 2
- How to use the new pessistent hook? HOT 1
- Reload auth fIle on the run HOT 2
- InlineClient模式下服务端订阅问题,inline subscribers do not receive messages HOT 5
- Merge 2 version of storm HOT 4
- Add Support for Disconnect With Will Message Reason Code
- Logging Level is not Configurable Via File Configuration
- Persistence storage did not work with SetCleanSession(false) HOT 3
- MessageExpiry Hook HOT 1
- OnConnectAuthenticate cannot specify an error code (like Client Identifier not valid)
- Resend timeout inflight messages
- Bug in inflight message restore from datastore
- Proposal: Add an Example for Custom Hook Usage
- can I use mqtts ? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from server.