I am using Istio as API Gateway and Service Mesh. The plan is to have the authentication and authorization flow (oauth2) being managed by the Ingress Envoy Gateway in Istio. However, the usage of Envoy filters are not redirecting the URL request to the login page as expected (the example followed can be found in here and the login is not happening. If I try to connect by curl (authenticate, use the token received to get the authorization), it works fine. But when involve the Oauth 2 flow, it gets stuck. This authorizations are being done using Keycloak.
This is the Lua Filter being used:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: authn-filter
namespace: istio-test
spec:
filters:
- filterConfig:
inlineCode: |
function login (request_handle)
request_handle:logInfo("logging in")
local request_url = "http://"..request_handle:headers():get(":authority")..request_handle:headers():get(":path")
request_handle:logInfo(request_url)
headers, body = request_handle:httpCall(
"outbound|3000||service-gatekeeper.istio-test.svc.cluster.local",
{
[":method"] = "POST",
[":path"] = "/oauth/authorize",
[":authority"] = request_handle:headers():get(":authority"),
["X-Auth-Request-Redirect"] = request_url
},
nil,
5000)
return headers, body
end
function envoy_on_request(request_handle)
local path = request_handle:headers():get(":path")
-- ignore metrics, liveness probe requests
request_handle:logInfo("Envoy on Request")
if path == "/" then
return
end
token = request_handle:headers():get("Authorization")
cookie = request_handle:headers():get("Cookie")
if token == nil and cookie == nil then
request_handle:logInfo("about to login")
headers, body = login(request_handle)
request_handle:respond(headers,body)
end
request_handle:logInfo("validating token against Certs")
local headers, body = request_handle:httpCall(
"outbound|8080||eseabyr-oauth2-proxy-innulic-test.svc.cluster.local",
{
[":method"] = "GET",
[":path"] = "/oauth/authorize",
[":authority"] = request_handle:headers():get(":authority"),
["Authorization"] = token,
["Cookie"] = cookie
},
nil,
5000)
local status
for header, value in pairs(headers) do
if header == ":status" then
status = value
end
end
request_handle:logInfo("token validation status:"..status)
if status == "401" then
headers, body = login(request_handle)
request_handle:respond(headers,body)
end
end
-- Called on the response path.
function envoy_on_response(response_handle)
local headers = response_handle:headers()
headers:add("X-Envoy-Ingress", os.getenv("HOSTNAME"))
end
filterName: envoy.lua
filterType: HTTP
listenerMatch:
listenerType: GATEWAY
Thank you.