我使用 Istio 作为 API 网关和服务网格。计划是让身份验证和授权流程(oauth2)由 Istio 中的 Ingress Envoy 网关管理。但是,Envoy 过滤器的使用并没有按预期将 URL 请求重定向到登录页面(可以在此处找到后面的示例并且登录没有发生。如果我尝试通过 curl 连接(身份验证,使用收到的令牌获得授权),它工作正常。但是当涉及 Oauth 2 流程时,它会卡住。这个授权是使用Keycloak完成的。
这是正在使用的 Lua 过滤器:
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
谢谢你。