Closed petemiron closed 6 months ago
thanks for your quick answer. This may be not the best place to discuss this, but I do not own the domain. I receive on the client side an authorization token I am supposed to validate on the server side, at login time, using custom rules (validate against public key retrieved by http, and check a few fields of the token). I wonder how it could be done in the nats ecosystem.
As far as I know the only way we support today is if you emedded the nats broker into your own code, you can then supply your own authentication logic.
You could have a bearer token delivered to the client. Or a normal creds file as well. Will that now work?
I saw https://github.com/nats-io/nats-server/pull/1149 and it is really close. IMHO there may be corner cases where a server side script for token validation may be usefull. But this PR is very close to offer Oauth2 compliant authenticaction, yes.
as an example there is a rfc that specifies how to validate the token (RFC 7662 I think), but the people I work with (automotive industry) ask for specific way to validate the token, so the parameters exposed in the PR may not be enough for all cases. IMHO it woud be nice to have some kind of plugin or external resolver pattern for custom token validation, as not every identity provider or deployment are not exactly following the spec. I agree that in strict oauth2 cases, it should be possible to implement validation through configuration file.
We wanted to go for nats back in 2017 but we missed this feature. Now, five and a half years later, we are working on a new platform and see this ticket is still pending, so again we will not be able to use nats. Are there any hot news/plans you could share regarding this request @derekcollison? Thanks in advance.
Are there any hot news/plans you could share regarding this request @derekcollison? Thanks in advance.
Its on the near term roadmap. As it's such a varied topic maybe you can expand a bit on exactly how you would want to see this work?
Thanks for that update @ripienaar
We use the message bus not only for internal microservice communication, but we expose it and connect every user that is using our platform's webinterface + our thick app to the message bus, to use its full potential. This can be up to 500k users in our case.
Pushing messages to a webinterface using fine graded subscribe patterns like app.message.<username>.new
enables us to reach out to a user (or a group of users like app.message.<groupId>.new
) just by allowing them to subscribe for a topic others are not allowed to subscribe for.
Each user sends his username + JWT in form of a password after establishing a connection which will be forwarded and validated by our own identity provider using HTTPs.
Why recreating the complete exchange logic across a horizontally scaled infrastructure to reach certain users being connected to different endpoints, when nats does exactly this?
@john-dev thanks, for the input sure it will be handy when we work on this.
Building something like this using nats server as a library is fairly trivial - have done a NATS server that calls a external auth in under a hour, but sure its not to everyones liking to build custom server binaries.
Exactly, using custom build binaries is not an option for us, unfortunately. I guess we wait then - hopefully not for another 5 years ;-)
The auth system is an already supported extension point, when calling the server from Go.
Can you outline what that exactly means?
Can you outline what that exactly means?
Ignoring whats involved in starting a nats server in go - we have many examples in tests - you can replace the auth system entirely with your own.
type MyAuth struct {
user string
pass string
}
func (a *MyAuth) Check(Check(c server.ClientAuthentication) bool {
opts := c.GetOpts()
return opts.Username == user && opts.Password == pass
}
You can now set this into the run time options CustomClientAuthentication
and the server will use that auth.
So this is a super simple example, but there in opts
you have access to the supplied JWT and much more, ip addresses, the TLS state is there and all sorts of things and can enable all you need.
To note this entirely replaces the built in auth system.
So the work to support external auth would be to work on this area, extend it to perhaps call external binaries or perhaps to call out over NATS in specially designated account for a service that can handle auth and so forth based on what users say they need, we're likely to start with something basic and expand over time.
Interesting. I managed to implement out own backend-auth logic, is there also an option for a custom permission source?
Yup, you can:
user := &server.User{
Username: "bob",
Account: "some_account_that_exists",
Permissions: &server.Permissions{
// set permissions
},
}
c.RegisterUser(user)
Sorry, Account is a handle to the server account that you can get with LookupOrRegisterAccount()
Thanks for that, i got authentication and permissions working. I will do some tests within our platform next week and check if thats a route we would like to go.
It is not ideal to have a custom build but well, nothing is perfect. Having this implemented as a module would still be appreciated for a lot of people i assume.
Indeed, not ideal, but maybe this gets you going and moving to whatever the final natively supported system we decide on will not be onerous.
Wow, I note I edited your earlier comment instead of commenting new - sorry about that, anyway we got there in the end!
Auth callouts and mapping external Authn to NATS Authz is top priority for 2.10 release. Along with the ability to reuse an existing connection.
Hi, is there a temporary branch where we can test this before release in its current state?
Yes, the dev
branch
NATS Authorization Callout I also need
@bruth I think this can now be closed as 2.10 has been released
Requirements
{ user: 'optional', permissions: { publish: ['foo.*'], subscribe: ['foo.*', 'bar.*'] } }
2.2. The credentials must be checked during client CONNECT. 2.3. The external auth provider may return a Time-to-Live (TTL) for authz data. 2.4. If a TTL is returned, the server should respect the TTL and re-request authn for the user on any new message sent to or received from that user after TTL expiration. 2.5. The external auth provider must provide a means for failover (eg. DNS round-robin, or multiple addresses in the configuration).Plugin Interface Mockup
For discussion, here is a mockup of a plugin interface that passes a context around. This pushes locking responsibility into the plugin itself. It is not complete by any stretch of the imagination.
Related Issues
428
429
369