Kong extends jwt plug-in to add blacklist verification

Kong Jwt plugin with blacklist

extend Official jwt plug-in , keep token expiration and signature verification, add query redis blacklist database according to jti, and implement forced offline.

Extended functions

  • Optimize the configuration parameters, delete the token obtained from cookie, support the token obtained from url and header, increase the redis configuration, and increase the default value.

  • Verify whether the payload contains jti, and no 401 is returned.

  • Verify whether jti is in blacklist, if 401 and corresponding value are returned.

use

  1. Add a service with url as http://mockbin.org/request

  1. Add a router with path of / mock

  1. Add the jwt plug-in. The configuration is as follows

  1. Call our authorization service to obtain an access'u token

  1. Add the key to the redis database as prefix+jti

  1. Carry the token to access the service and verify the result

Core code

{ redis_host = {
                    type = "string",
                    required = true,
                    default = "127.0.0.1"
                } },
                { redis_port = {
                    type = "number",
                    required = true,
                    default = 6379
                } },
                { redis_db = {
                    type = "number",
                    required = true,
                    default = 0
                } },
                { redis_password = {
                    type = "string",
                } },
                { string_key_prefix = {
                    type = "string",
                    required = true,
                    default = "userOffline:"
                } },
function checkJti(conf, jti)
    if not jti then
        return false, { status = 401, message = "Invalid jti in claims" }
    end
    local red = redis:new()
    red:set_timeout(1000)
    local ok, err = red:connect(conf.redis_host, conf.redis_port)
    if not ok then
        kong.log.err("failed to connect : ", err)
        return
    end
    if conf.redis_password and conf.redis_password ~= "" then
        local count
        count, err = red:get_reused_times()
        if 0 == count then
            ok, err = red:auth(conf.redis_password)
            if not ok then
                kong.log.err("failed to auth: ", err)
                return
            end
        elseif err then
            kong.log.err("failed to get reused times: ", err)
            return
        end
    end
    ok, err = red:select(conf.redis_db)
    if not ok then
        kong.log.err("failed to select db: ", err)
        return
    end
    -- get key
    local res, err = red:get(conf.string_key_prefix .. jti)
    kong.log.notice("red:get:", conf.string_key_prefix .. jti, ",value=", res)
    if err then
        kong.log.err("failed to get key", conf.string_key_prefix .. jti)
    end
    --The connection pool size is 100, and the maximum idle time set is 10 seconds
    ok, err = red:set_keepalive(10000, 100)
    if not ok then
        kong.log.err("failed to set keepalive: ", err)
        return
    end
    if res ~= ngx.null then
        return false, { status = 401, message = res }
    end
    return true
end

‚Äč

Tags: Programming Redis Database

Posted on Fri, 15 May 2020 07:15:22 -0700 by Consolas