lua-resty-openidc icon indicating copy to clipboard operation
lua-resty-openidc copied to clipboard

missing session cookie - from lua resty openidc

Open dhavalkshah opened this issue 1 year ago • 8 comments

Context: I am trying to use Kong + OpenIDC (Custom plugin), based on nokia/kong-oidc The setup is using docker desktop.

I run luarocks install lua-resty-openidc while building the custom kong image.

Following the code-snippet from my handler.lua:

local res, err = require("resty.openidc").authenticate(oidcConfig)
    if err then
        if oidcConfig.recovery_page_path then
            ngx.log(ngx.NOTICE, "Entering recovery page: " .. oidcConfig.recovery_page_path)
            ngx.redirect(oidcConfig.recovery_page_path)
        end
        utils.exit(500, err, ngx.HTTP_INTERNAL_SERVER_ERROR)
    end

I get the following error: attempt to call method 'start' (a nil value), client: 172.18.0.1, server: kong, request: "GET /mock HTTP/1.1", host: "localhost:8000", request_id: "7df8870a8d3fa916cf1c5a540f2b9f3f"

I figured that it was from session:start() present in openidc. It seemed that session was not getting initialized, so I tried similar in my local handler.lua. Following is the code from my local handler.lua (inspired from openidc)

    local session, err, ret = require("resty.session").open(nil)
    if (session ~= nil) then
        ngx.log(ngx.NOTICE,"session is not nil")
        ngx.log(ngx.DEBUG,
            "session.present=", session.present,
            ", session.data.id_token=", session.data.id_token ~= nil,
            ", session.data.authenticated=", session.data.authenticated,
            ", err=", err,
            ", ret=",ret
        )
        session:start()
    else
        ngx.log(ngx.NOTICE, "Session is nil")
    end

I observe that session is not null and err is printed is as "missing session cookie". Here is the snippet of the logs

2024-10-07 11:16:12 2024/10/07 05:46:12 [notice] 2413#0: *20313 [lua] handler.lua:73: make_oidc(): OidcHandler calling authenticate, requested path: /mock, client: 172.18.0.1, server: kong, request: "GET /mock HTTP/1.1", host: "localhost:8000", request_id: "7df8870a8d3fa916cf1c5a540f2b9f3f"
2024-10-07 11:16:12 2024/10/07 05:46:12 [notice] 2413#0: *20313 [lua] handler.lua:76: make_oidc(): session is not nil, client: 172.18.0.1, server: kong, request: "GET /mock HTTP/1.1", host: "localhost:8000", request_id: "7df8870a8d3fa916cf1c5a540f2b9f3f"
2024-10-07 11:16:12 2024/10/07 05:46:12 [debug] 2413#0: *20313 [lua] handler.lua:77: make_oidc(): session.present=nil, session.data.id_token=false, session.data.authenticated=nil, err=missing session cookie, ret=false
2024-10-07 11:16:12 2024/10/07 05:46:12 [error] 2413#0: *20313 [kong] init.lua:426 [fountane-oidc] ...cal/share/lua/5.1/kong/plugins/fountane-oidc/handler.lua:84: attempt to call method 'start' (a nil value), client: 172.18.0.1, server: kong, request: "GET /mock HTTP/1.1", host: "localhost:8000", request_id: "7df8870a8d3fa916cf1c5a540f2b9f3f"

Not sure what am I missing here. Any pointers are appreciated.

dhavalkshah avatar Oct 07 '24 09:10 dhavalkshah

That is strange. There are two calls to start, both are on r_session (i.e. r_session.start), which is assigned on the top of openidc.lua to local r_session = require("resty.session"). Is this really an issue of lua-resty-openidc?

Edit: I see a call to session.present, which is not present in lua-resty-session 4.x.x, which is used by Kong in recent versions. So please be aware that you also need latest lua-resty-openidc 1.8.0. With version of lua-resty-session before 4.x.x you need lua-resty-openidc 1.7.6. The session object returned by lua-resty-session is not backwards compatible.

oldium avatar Oct 07 '24 09:10 oldium

Hey @oldium - Thanks for the early response.

Not sure if I can classify this as openidc issue or not, but I am invoking authenticate method of openidc. This internally is using resty-session. Although the initialization seems to be fine, but it is failing while starting the session.

openidc is not really catching the error, thus I just put the code-snippet of session in my handler.lua to see whats the actual error from resty-session. The error message that I see is "missing session cookie" :(

Per se the versions that you mentioned, when I hook on to the kong container, below is the output I see:

# luarocks list lua-resty-openidc

Rocks installed for Lua 5.1
---------------------------

lua-resty-openidc
   1.8.0-1 (installed) - /usr/local/lib/luarocks/rocks-5.1

# luarocks list lua-resty-session

Rocks installed for Lua 5.1
---------------------------

lua-resty-session
   4.0.5-1 (installed) - /usr/local/lib/luarocks/rocks-5.1

# 

dhavalkshah avatar Oct 07 '24 10:10 dhavalkshah

If it is really inside lua-resty-openidc, then the only explanation I can think of is that require("resty.session") returned nil for some reason. The call in lua-resty-openidc is equivalent to require("resty.session").start(nil).

oldium avatar Oct 07 '24 14:10 oldium

Thanks @oldium

That is exactly what I was thinking, that require("resty.session").open(nil) returned nil. But that doesn't seem to be the case. As I stated, I tried to simulate the similar code in my handler.lua to trap the error, using the below code.

    local session, err, ret = require("resty.session").open(nil)
    if (session ~= nil) then
        ngx.log(ngx.NOTICE,"session is not nil")
        ngx.log(ngx.DEBUG,
            "session.present=", session.present,
            ", session.data.id_token=", session.data.id_token ~= nil,
            ", session.data.authenticated=", session.data.authenticated,
            ", err=", err,
            ", ret=",ret
        )
        session:start()
    else
        ngx.log(ngx.NOTICE, "Session is nil")
    end

Here I see that the control does enter the if construct suggesting that session is not null. But it also has err initialized assigned as well. The err being printed in the log as err=missing session cookie,

:(

dhavalkshah avatar Oct 07 '24 14:10 dhavalkshah

That is fine and expected. The third return value is called exists, which is false. The require("resty.session").open(nil) call simply tells you that the cookie does not exist, so there is no session.

lua-resty-session has start() method, which does everything you need:

function session.start(configuration)
  local self, err, exists = session.open(configuration)
  if not exists then
    return self, err, false, false
  end

  local refreshed, err = self:refresh()
  if not refreshed then
    return self, err, true, false
  end

  return self, nil, true, true
end

This method is called as require("resty.session").start(nil) directly. There is no start() method on the session instance returned from require("resty.session").open(nil), please see documentation for lua-resty-session here.

So I guess that the nil error comes from your code (method was not found), not from lua-resty-openidc.

oldium avatar Oct 07 '24 15:10 oldium

Thank @oldium Your pointer regarding the version did help.

Firstly, to answer your previous point - I was just calling local res, err = require("resty.openidc").authenticate(oidcConfig) But that gave the same error as I got it in my version of the code. i.e. attempt to call method 'start' (a nil value) My version of the code was more to check on why I was getting the error.

But I guess the current versions are incompatible somehow. I have downgraded- Kong to 3.1 lua-resty-session to 3.10 lua-resty-openidc to 1.7.6

and life is smooth again :)

dhavalkshah avatar Oct 07 '24 17:10 dhavalkshah

I just tried our plugin in custom Kong image based on kong/kong-gateway:3.8.0.0-ubuntu, it has lua-resty-session 4.0.5 and lua-resty-openidc 1.8.0. The following call works without any issues:

local restyOpenidc = require "resty.openidc"
local res, err = restyOpenidc.authenticate(pluginConfig.openidc, kong.request.get_forwarded_path(), nil, pluginConfig.session) 

oldium avatar Oct 08 '24 18:10 oldium

Do you have any more questions? Otherwise I think we can close the issue.

oldium avatar Oct 14 '24 09:10 oldium