-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
feat: add support for password grant in authz-keycloak plugin #6586
feat: add support for password grant in authz-keycloak plugin #6586
Conversation
Squashed commit: [99ff9f4] refactor: Removing unnecessary properties (apache#6574) Removing unnecessary properties and test codes. And also improve document for Token generation feature. feat: apache#6574 [22c8d8e] feat: Support of password grant type for token generation (apache#6574) Committing changes after adding new feature for generating token based on `user id/password` and also taking support of grant type `password` feat: apache#6574
you should sing the CLA first |
Missing unit tests |
e555a00
to
3d1e27b
Compare
Better variable names. Documentation updated as per guideline.
3d1e27b
to
fc96102
Compare
Hi, I will need little guidance for the CLA signing process from your side. In PR, I have made the following changes.
Please let me know the next actions for me. |
…using password_grant_token_generation_incoming_uri. I have removed some more errors reported by git workflow build process.
There is no CLA file for APISIX :)
As the keycloak environment is set up by @sshniro, |
I checked the logs of above test runs. I have used following settings in my test scenario: I took the above settings from other Keycloak test cases. And it worked properly. Another issue is reported as: "ERROR: apisix/plugins/authz-keycloak.lua: line 719: getting the Lua global "string"" For which I made fix "local str_find = string.find", so it should be fixed now. |
apisix/plugins/authz-keycloak.lua
Outdated
@@ -695,8 +703,107 @@ local function fetch_jwt_token(ctx) | |||
return token | |||
end | |||
|
|||
-- To get new access token by calling get token api | |||
local function generate_token_using_password_grant(conf,ctx) | |||
log.warn("generate_token_using_password_grant Function Called") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should we use warn
level ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree... it should be debug level log. I changed it.
apisix/plugins/authz-keycloak.lua
Outdated
--Read Body | ||
ngx.req.read_body() | ||
--Get Body Data | ||
local request_body=ngx.req.get_body_data() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use core.request.get_body()
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I changed it.
apisix/plugins/authz-keycloak.lua
Outdated
return 401, {message = err} | ||
end | ||
|
||
return res.status, res.body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return res.status, res.body | |
return res.status, res.body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
apisix/plugins/authz-keycloak.lua
Outdated
|
||
if conf.password_grant_token_generation_incoming_uri then | ||
if ngx.var.request_uri:upper() | ||
== conf.password_grant_token_generation_incoming_uri:upper() then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use and
would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good Suggestion and changed it to use and for all three conditions.
apisix/plugins/authz-keycloak.lua
Outdated
local username = nil | ||
local password = nil | ||
--split by & | ||
local parameters_array = util.split(request_body, "&") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the username, password in the request body and use & to concat.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As url encoded parameters were coming, they were automatically appended using '&'. Having said that, your comment helped me to utilize "ngx.decode_args" which makes code much cleaner. Thanks!
Used ngx.decode_args for input arguments.
Hi, are you getting the same error when you run the docker image instance (sshniro/keycloak-apisix:latest) locally? |
@sshniro I have got the idea what things might cause that. Earlier I was using '&' to split the incoming parameters. but now I am using "ngx.decode_args" ( #6586 (comment) ). Because of that earlier, username (which is email) wouldn't parse properly. |
apisix/plugins/authz-keycloak.lua
Outdated
if conf.password_grant_token_generation_incoming_uri and | ||
ngx.var.request_uri:upper() == | ||
conf.password_grant_token_generation_incoming_uri:upper() and | ||
ctx.curr_req_matched["_method"]:upper() == "POST" then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ctx.curr_req_matched["_method"]:upper()
looks strange.
I think you can use core.req.get_method
instead.
apisix/plugins/authz-keycloak.lua
Outdated
|
||
function _M.access(conf, ctx) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant line ?
@@ -122,6 +123,27 @@ of the same name. The scope is then added to every permission to check. | |||
If `lazy_load_paths` is `false`, the plugin adds the mapped scope to any of the static permissions configured | |||
in the `permissions` attribute, even if they contain one or more scopes already. | |||
|
|||
### Password Grant Token Generation Incoming URI | |||
|
|||
If you want to generate a token using `password` grant, you can set value of `password_grant_token_generation_incoming_uri`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to generate a token using `password` grant, you can set value of `password_grant_token_generation_incoming_uri`. | |
If you want to generate a token using `password` grant, you can set the value of `password_grant_token_generation_incoming_uri`. |
|
||
If you want to generate a token using `password` grant, you can set value of `password_grant_token_generation_incoming_uri`. | ||
|
||
Incoming request URI will be matched with this value and if matched, it will generate token using `Token Endpoint`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incoming request URI will be matched with this value and if matched, it will generate token using `Token Endpoint`. | |
Incoming request URI will be matched with this value and if matched, it will generate a token using `Token Endpoint`. |
If you want to generate a token using `password` grant, you can set value of `password_grant_token_generation_incoming_uri`. | ||
|
||
Incoming request URI will be matched with this value and if matched, it will generate token using `Token Endpoint`. | ||
It will also check, if REST method is `POST`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will also check, if REST method is `POST`. | |
It will also check if the request method is `POST`. |
apisix/plugins/authz-keycloak.lua
Outdated
|
||
local params = { | ||
method = "POST", | ||
body = ngx.encode_args({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
body = ngx.encode_args({ | |
body = ngx.encode_args({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done and also incorporated this in the same file at other places.
apisix/plugins/authz-keycloak.lua
Outdated
if not token_endpoint then | ||
local err = "Unable to determine token endpoint." | ||
log.error(err) | ||
return 500, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return 500, err | |
return 503, err |
New feature is encouraged to avoid 500
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Valid point. I updated it. I didn't update at other places because there can be backward compatibility issues and there should be separate PR for the same.
apisix/plugins/authz-keycloak.lua
Outdated
if conf.password_grant_token_generation_incoming_uri and | ||
ngx.var.request_uri:upper() == | ||
conf.password_grant_token_generation_incoming_uri:upper() and | ||
core.request.get_method() == "POST" then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also check the "Content-Type"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. it was missed. I introduced that now.
apisix/plugins/authz-keycloak.lua
Outdated
|
||
function _M.access(conf, ctx) | ||
if conf.password_grant_token_generation_incoming_uri and | ||
ngx.var.request_uri:upper() == | ||
conf.password_grant_token_generation_incoming_uri:upper() and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it required to compare case-insensitive?
Also, the var.request_uri
will contain ?argument=part
, is it desirable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL should be case sensitive so removed that "upper" from code.
For the part of request_uri, I believe, as we are checking uri, method, and header, all three parts, this should be fine.
Basically for the operation of token generation, exact uri matching will be helpful.
Your thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The request_uri
will contain the query string part of the uri. For example,
With request /path?query=string
The ngx.var.request_uri
will return /path?query=string
, and ctx.var.uri
will return /path
. By looking at the doc of password_grant_token_generation_incoming_uri
, I guess we can use ctx.var.uri
so both /path?query=string
and /path
can match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@spacewander I understood your idea. I am curious, as to why we should treat both strings (/path?query=string or /path) the same way and proceed with token generation.
Token generation is a very specific use case, and shouldn't we say if and only if a specific URL will be submitted then we will generate token and submit result back.
if the request is made with /path?query=string, it shouldn't be assumed for token generation and it should be treated the same as any other request. (e.g. proceed to forward to upstream for further processing).
Please share your view. Accordingly, I can make changes, if needed.
t/plugin/authz-keycloak.t
Outdated
}, | ||
"uri": "/api/token" | ||
}]], | ||
[[{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to remove the echo response data as #6545
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright. I removed it from this new test case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved except #6586 (comment)
6f04d1a
to
c1d1c8d
Compare
apisix/plugins/authz-keycloak.lua
Outdated
|
||
function _M.access(conf, ctx) | ||
local headers = core.request.headers(ctx) | ||
local need_grant_token = conf.password_grant_token_generation_incoming_uri and | ||
ngx.var.request_uri == conf.password_grant_token_generation_incoming_uri and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ngx.var.request_uri == conf.password_grant_token_generation_incoming_uri and | |
ctx.var.request_uri == conf.password_grant_token_generation_incoming_uri and |
would be better, which provides a cache of the var.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Made the change.
Hi @azilentech , thank you for your contribution! Here is the Contributor T-shirt form[1], if you're interested, kindly take a look :) [1] https://github.com/apache/apisix/blob/master/CONTRIBUTING.md#contributor-t-shirt |
Support of password grant type for token generation (#6574)
Committing changes after adding new feature for generating token based on
user id/password
and also taking support of grant typepassword
feat: #6574
Pre-submission checklist: