You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2022/03/14 01:31:01 UTC

[GitHub] [apisix] starsz commented on a change in pull request #6586: feat: add support for password grant in keycloak plugin

starsz commented on a change in pull request #6586:
URL: https://github.com/apache/apisix/pull/6586#discussion_r825536697



##########
File path: apisix/plugins/authz-keycloak.lua
##########
@@ -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")
+    --Read Body
+    ngx.req.read_body()
+    --Get Body Data
+    local request_body=ngx.req.get_body_data()

Review comment:
       You can use `core.request.get_body()` instead.

##########
File path: apisix/plugins/authz-keycloak.lua
##########
@@ -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")

Review comment:
       Why should we use `warn` level ?

##########
File path: apisix/plugins/authz-keycloak.lua
##########
@@ -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")
+    --Read Body
+    ngx.req.read_body()
+    --Get Body Data
+    local request_body=ngx.req.get_body_data()
+    local username = nil
+    local password = nil
+    --split by &
+    local parameters_array = util.split(request_body, "&")
+
+    if #parameters_array == 2 then
+        for k, parameter in ipairs(parameters_array) do
+            if str_find(parameter, "username") then
+                --split by =
+                local username_value_array = util.split(parameter, "=")
+                if #username_value_array == 2 then
+                    username = username_value_array[2]
+                end
+            end
+            if str_find(parameter, "password") then
+                --split by =
+                local password_value_array = util.split(parameter, "=")
+                if #password_value_array == 2 then
+                    password = password_value_array[2]
+                end
+            end
+        end
+    end
+
+    if not username then
+        local err = "username is missing"
+        log.error(err)
+        return 422, err
+    end
+    if not password then
+        local err = "password is missing"
+        log.error(err)
+        return 422, err
+    end
+
+    local client_id = authz_keycloak_get_client_id(conf)
+
+    local token_endpoint = authz_keycloak_get_token_endpoint(conf)
+
+    if not token_endpoint then
+        local err = "Unable to determine token endpoint."
+        log.error(err)
+        return 500, err
+    end
+    local httpc = authz_keycloak_get_http_client(conf)
+
+    local params = {
+        method = "POST",
+        body =  ngx.encode_args({
+            grant_type = "password",
+            client_id = client_id,
+            client_secret = conf.client_secret,
+            username = username,
+            password = password
+        }),
+        headers = {
+            ["Content-Type"] = "application/x-www-form-urlencoded"
+        }
+    }
+
+    params = authz_keycloak_configure_params(params, conf)
+
+    local res, err = httpc:request_uri(token_endpoint, params)
+
+    if not res then
+        err = "Accessing token endpoint URL (" .. token_endpoint
+              .. ") failed: " .. err
+        log.error(err)
+        return 401, {message = err}
+    end
+
+    log.debug("Response data: " .. res.body)
+    local json, err = authz_keycloak_parse_json_response(res)
+
+    if not json then
+        err = "Could not decode JSON from response"
+              .. (err and (": " .. err) or '.')
+        log.error(err)
+        return 401, {message = err}
+    end
+
+    return  res.status, res.body
+end
 
 function _M.access(conf, ctx)
+
+    if conf.password_grant_token_generation_incoming_uri then
+        if ngx.var.request_uri:upper()
+                == conf.password_grant_token_generation_incoming_uri:upper() then

Review comment:
       Use `and` would be better.

##########
File path: apisix/plugins/authz-keycloak.lua
##########
@@ -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")
+    --Read Body
+    ngx.req.read_body()
+    --Get Body Data
+    local request_body=ngx.req.get_body_data()
+    local username = nil
+    local password = nil
+    --split by &
+    local parameters_array = util.split(request_body, "&")
+
+    if #parameters_array == 2 then
+        for k, parameter in ipairs(parameters_array) do
+            if str_find(parameter, "username") then
+                --split by =
+                local username_value_array = util.split(parameter, "=")
+                if #username_value_array == 2 then
+                    username = username_value_array[2]
+                end
+            end
+            if str_find(parameter, "password") then
+                --split by =
+                local password_value_array = util.split(parameter, "=")
+                if #password_value_array == 2 then
+                    password = password_value_array[2]
+                end
+            end
+        end
+    end
+
+    if not username then
+        local err = "username is missing"
+        log.error(err)
+        return 422, err
+    end
+    if not password then
+        local err = "password is missing"
+        log.error(err)
+        return 422, err
+    end
+
+    local client_id = authz_keycloak_get_client_id(conf)
+
+    local token_endpoint = authz_keycloak_get_token_endpoint(conf)
+
+    if not token_endpoint then
+        local err = "Unable to determine token endpoint."
+        log.error(err)
+        return 500, err
+    end
+    local httpc = authz_keycloak_get_http_client(conf)
+
+    local params = {
+        method = "POST",
+        body =  ngx.encode_args({
+            grant_type = "password",
+            client_id = client_id,
+            client_secret = conf.client_secret,
+            username = username,
+            password = password
+        }),
+        headers = {
+            ["Content-Type"] = "application/x-www-form-urlencoded"
+        }
+    }
+
+    params = authz_keycloak_configure_params(params, conf)
+
+    local res, err = httpc:request_uri(token_endpoint, params)
+
+    if not res then
+        err = "Accessing token endpoint URL (" .. token_endpoint
+              .. ") failed: " .. err
+        log.error(err)
+        return 401, {message = err}
+    end
+
+    log.debug("Response data: " .. res.body)
+    local json, err = authz_keycloak_parse_json_response(res)
+
+    if not json then
+        err = "Could not decode JSON from response"
+              .. (err and (": " .. err) or '.')
+        log.error(err)
+        return 401, {message = err}
+    end
+
+    return  res.status, res.body

Review comment:
       ```suggestion
       return res.status, res.body
   ```

##########
File path: apisix/plugins/authz-keycloak.lua
##########
@@ -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")
+    --Read Body
+    ngx.req.read_body()
+    --Get Body Data
+    local request_body=ngx.req.get_body_data()
+    local username = nil
+    local password = nil
+    --split by &
+    local parameters_array = util.split(request_body, "&")

Review comment:
       Why the username, password in the request body and use & to concat.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org