nokia / kong-oidc

OIDC plugin for Kong
Apache License 2.0
455 stars 320 forks source link

Query parameter 'Code' to upstream service behind the kong #176

Open mssaisandeep opened 3 years ago

mssaisandeep commented 3 years ago

I am using this plugin for a long time. I have a use case, where there is an application hosted behind the kong. That application is having a query parameter named "code". Whenever we try to access the application with query parameter code, kong is being redirected to the recovery page.

Example:

https://kong/application1?code=xxxxxxx

Note: Application1 is hosted behind kong with kong-oidc plugin configured. image

I know that it is in conflict with the actual authorization code oidc process. (as it also uses 'code' as a query parameter). But after a successful login, I am trying to use the upstream Application1's API with query parameter code (which is application-specific). Is there any way to acheive this?

@Trojan295 Need your help in understanding exactly what is happening and how can we fix (if any). Let me know. Thanks

mssaisandeep commented 3 years ago

Possible Theoretical Solution: (Feel free to comment with best solutions if any)

The following is the snippet from the Utils.lua (line number 26).

local function tackle_slash(path)
    local args = ngx.req.get_uri_args()
    if args and args.code then
      return path
    elseif path == "/" then
      return "/cb"
    elseif path:sub(-1) == "/" then
      return path:sub(1, -2)
    else
      return path .. "/"
    end
  end

Here we are checking if the args (query params of a request) are having 'code' or not, if so, it will consider the request is for authorization so it passes the redirect_uri_path to lua-resty-openidc (which in turn triggers this if loop https://github.com/zmartzone/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L1405).

So instead of just checking args, args.code, we will also check one more thing: referrer header value is from OP (IDP) or not. If it is then we will consider the request is for authorization and pass it to lua-resty-openidc. If not, we will treat that as upstreams query parameter 'code' and we will just proxy it (means it will go to the last else block in the above snippet).

local function tackle_slash(path)
    local args = ngx.req.get_uri_args()
    if args and args.code and referrer_header and (referrer_header:match("://(.-)/") == idp_domain)then
      return path
    elseif path == "/" then
      return "/cb"
    elseif path:sub(-1) == "/" then
      return path:sub(1, -2)
    else
      return path .. "/"
    end
  end

Note: referrer_header = You can get it from request idp_domainname = You can pass it to the plugin through configuration (as the internal IDP's domain name is well known and static)

How about this?? I don't know whether this will work or not. This is just a theoretical approach.