roadrunner
roadrunner copied to clipboard
[💡FEATURE REQUEST]: Authorization plugin [JWT]
Describe the solution you'd like For example: EMQX has multiple authorisation plugins - http, mysql, redis etc. Considering that a lot of people use RR for microservices with JWT, authorization could be moved to it too.
Example config
auth:
config: // this could be for each auth method, there for you can have multiple auth methods at once.
header: Authorization
query: token
body: token
timeout: 180 // ttl for cached authorization
jwt: // does check jwt, append decoded info to attributes
config:
public: ...
worker: ~ // send auth request over worker like Broadcast plugin does. Everything that workers returns is appended to user "session" and that data is appended to attributes in next request
http: ~ // append headers etc and send further and wait for 2** response
kv: ~ // key found and append its content to attributes
sql:
config:
table: token
passwd: ~
list: ~ // basic auth
config:
hash: md5
users:
- username: SomeUser
password: 5f4dcc3b5aa765d61d8327deb882cf99
For now only JWT makes sense. Example in practice: https://docs.emqx.io/en/broker/v4.3/advanced/auth.html#password-salting-rules-and-hash-methods
Hey @OO00O0O , thanks for the FR.
I'm not quite sure, that I correctly understand your proposal. Could you please provide more details, especially about how other plugins will collaborate with the auth
plugin and what data they should send to it? And full configuration, w/o ~
.
For example, what should be done for the http
plugin (in terms of authorization), if the auth
plugin exists?
View of this functionality really depends on how you see RR in future and now. Me personally see it as http/ws application server/framework. I do not care about GRPC or Temporal. So I do not consider them in this example.
auth: // maybe this could be middleware for http
config: // here we tell RR what http query/header(maybe body) parameters to use
header: Authorization
query: token
authenticators: [jwt-auth, worker-auth] // executes in order
jwt-auth:
type: jwt
public: ...
fail: ignore
worker-auth:
type: worker
ttl: 3600
fail: deny
Flow: Client first time access service with expired JWT token in header Authorization
- RR sees used authorization header and takes its
value
- Because in
auth.config.authenticators
jwt-auth is first, it sendsvalue
to it. - jwt-auth sees that it's invalid query and there for returns
false
- Because
auth.jwt-auth.fail == ignore
it ignores failure and send further - worker-auth uses same token to reauthorze. If it succeed it cashes return value with timeout
- Now it attaches object to each http requests attributes.
Main idea is, that RR should handle generic cases, so: authorization, cache, database, websockets, etc. AND only send work to workers that actually should be done. I would even consider templating engine, where php worker responds with object.
Ok, I got your idea. Generally, handling bad or expired JWT's on the server side might be a good idea (to free up workers' resources and pass only valid headers). But... ...to get good feedback from the other users, would be a great practice to make a detailed FR, especially, if you want a new plugin. From your proposal, I see only a JWT sample, it's fine. Imagine If I start working on your proposal w/o any information about other details. It would be a mess. So, make a detailed proposal, including all keys you think should be in the configuration. I'm not asking, but, would be nice if you provide some diagrams about the flow. Make a detailed explanation about every config key, you want to include. Then we will wait for other users' feedback and if your proposal passes the review, I'll be happy to implement this.
Sorry, but I think this is discussion first - implementation later. Maybe it's not worth your a time. We should wait for more input from community or spiral dev team.
np, I respect your time as much as I respect mine 😃
spiral dev team
np, I'll ask PHP teammates at tomorrow daily :) Please, keep in mind, a good discussion is only possible with a detailed proposal :) People should clearly understand, what do mean by your proposal and then productively discuss it :) Also, keep in mind, that I'm not a PHP dev at all, so, I have to understand, how do you want to use this feature and how this feature will be used by the community :P
Main problem for me is that I do not know what PHP devs prefer - voters or roles. Be more implicit or explicit. Therefor it's hard to write good proposal that would pass.
I personally prefer configuring generic functionality and writing specific code. Others will do configurations and abstractions till death. And some people can write http servers almost in one line when they need them and ignore configurations at all.
I personally prefer configuring generic functionality and writing specific code. Others will do configurations and abstractions till death. And some people can write http servers almost in one line when they need them and ignore configurations at all.
In your proposal, you have to cover all these options.