krakend / krakend-lua

a lua interpreter for the KrakenD framework
Apache License 2.0
7 stars 14 forks source link

KrakenD endpoints validation #10

Closed soulless-viewer closed 4 years ago

soulless-viewer commented 4 years ago

I was faced with the problem of insufficient functionality of the cat build a chain of queries.

What I want:

When accepting a request for a specific endpoint, the service must take information from this request and make a new one in order to check (validate) the received request. After successful verification, the initial request continues.


Example:

[1]Client - - - > [2]<krakend> / api/service/project1/secret-info - - - > [3]<server>/project1/secret-info

1. Send JWT in auth header (with userID) 2.1. Get userID from JWT & projectID from URL 2.2. Send UID & GID to /api/check-users-project 2.3. Check response (if access denied - abort, if access allowed - continue) 3. Accepts a normal request


What I did:

1. Tried using a Sequential Proxy, but it's not exactly what I need. This scheme cannot terminate requests if verification fails. 2. Tried to use a Checking requests and responses with CEL in the request chains. The check works, but it still fails to terminate requests. 3. Trying to use Lua scripts. Everything was fine, but I ran into the current problem.


Main question:

I want to use Lua scripts to send https requests using "socket" and "luasec". This would solve my problem, but I don't see a way to use .so files for Lua inside Krakend.

Simple config example:

{
    "endpoint": "/api/secret",
    "method": "GET",
    "extra_config": {
        "github.com/devopsfaith/krakend-lua/request": {
            "sources": [
                "/etc/krakend/lua/validateRequest.lua",        <--- (1)
                "/etc/krakend/lua/socket.lua",                       <--- (2)
                "/etc/krakend/lua/https.lua",                          <--- (3)
                "/etc/krakend/lua/socket/core.so"                 <--- (4)
            ],
            "pre": "validateRequest(ctx.load())",
            "live": true,
            "allow_open_libs": true
        }
    },
    "backend": [
        {
            "extra_config": {
                "github.com/devopsfaith/krakend-cel": [
                    {
                        "check_expr": "'True' in req_headers['Krakend-Access']"
                    }
                ]
            },
            "host": [
                "http://<ip:port>"
            ],
            "url_pattern": "/secret",
            "encoding": "json"
        }
    ]
}

(1) validateRequest.lua:

local socket = require "socket"   <--- OK
...

(2) socket.lua:

local socket = require "https"   <--- OK
...

(3) https.lua:

local socket = require "socket/core"   <--- this is core.so and KrakenD can't load or find this module inside
...

I will be grateful for advice on an alternative solution or how to fix the current algorithm. For everything in general. Thanks

kpacha commented 4 years ago

The LUA engine is a pure go implementation and does not work with c libs (.so)

You can use the http_response helper https://www.krakend.io/docs/endpoints/lua/#supported-lua-types-cheatsheet

Here you have a working example: https://github.com/devopsfaith/krakend-lua/blob/master/proxy/http_test.go#L66-L82

soulless-viewer commented 4 years ago

@kpacha Thank you for the answer, but I couldn't use this example.

Error: Error #01: Line 2: attempt to index a non-table object(nil)

Script:

function validateRequest( ctx )
        local r = http_response.new('172.20.242.119/check', "POST", '{"user":"' .. user .. '", "project": "' .. project .. '"}')
        print(r:statusCode())
        print(r:body())
end

krakend.json (part):

{
      "endpoint": "/api/secret",
      "extra_config": {
        "github.com/devopsfaith/krakend-lua/router": {
                "sources": [
                        "/etc/krakend/lua/validateRequest.lua"
                ],
                "pre": "validateRequest(ctx.load())",
                "live":true,
                "allow_open_libs": true
        }
      },
      "output_encoding": "no-op",
      "backend": [
        {
          "url_pattern": "/secret",
          "encoding": "no-op",
          "host": [
             "http://<ip>:<port>"
          ]
        }
      ]
    }
kpacha commented 4 years ago

the no-op encoding does not support data manipulation in any way. try removing the output_encoding and the encoding keys and it should work.

cheers!

soulless-viewer commented 4 years ago

The problem was solved by switching from roter scope to the proxy. no-op does not affect the operation

prakashdivyy commented 3 years ago

Hello @soulless-viewer, I have followed your implementation by using proxy instead of router scope but I still facing the issue about http_response as followed in https://github.com/devopsfaith/krakend-lua/issues/10#issuecomment-673931219

Could you share your implementation after you switching to proxy?

caiobsilva commented 3 years ago

Hey, @prakashdivyy. Guess I'm kind of late in here, but maybe this will be useful for someone. Following from config that was set up in this thread, the context should now be the request:

"github.com/devopsfaith/krakend-lua/router": {
    "sources": ["etc/krakend/lua/validateRequest.lua"],
    "pre": "validateRequest(request.load())",
    "live":true,
    "allow_open_libs": true
}

You should then be able to manipulate your new request through the http_response helper.

I think the docs could be clearer about Lua scripting and limitations on sequential requests.

prakashdivyy commented 3 years ago

Thanks @caiobsilva for the reply.

After I upgrade the KrakenD to the latest version it seems that it worked normally, so maybe I think there is a bug inside one of KrakenD dependencies.

github-actions[bot] commented 2 years ago

This issue was marked as resolved a long time ago and now has been automatically locked as there has not been any recent activity after it. You can still open a new issue and reference this link.