2

我使用 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

谢谢你。

4

1 回答 1

0

由于我没有您环境的完整详细信息,因此我可以建议以下方法来调试问题:

  1. 我看到您没有工作负载标签,这意味着此过滤器应附加到网格中的所有 pod。
  2. 确保将 istio init 容器注入到您的 pod(使用 istioctl 或使用 k8s 准入控制器)
  3. 检查附加到您感兴趣的 pod 的 sidecar 代理的日志。我猜有一些语法错误,这将完全禁用过滤器。否则它应该告诉你过滤器出了什么问题。
于 2019-05-07T17:30:39.307 回答