istio使用lua脚本实现外部授权

使用场景

istio具有外部授权扩展,可以通过开发外部扩展的方式,到访问进行授权拦截,可参考官方的外部授权例子。但在实际应用中,外部授权已经存在了,或者是第三方的应用,不可能再重新开发了,这时使用官方的外部授权的例子已经适合了,但好在istio有好的扩展性,可以使用istio的EnvoyFilter的lua脚本功能,连接到外部授权。最近项目中有个需求,需要使用已经存在的外部服务提供istio的访问授权,查看了istio的EnvoyFilter配置实例,决定采用EnvoyFilter的lua扩展,通过lua扩展中的httpCall功能调用授权服务。lua http扩展就是envoy的扩展,详细参照这里。下面摘取httpCall()进行简单说明:

httpCall()

注意这个方法需要放到function envoy_on_request(request_handle)方法里,因为这个方法是request_handle的一个方法。

function envoy_on_request(request_handle)
  -- 使用下面的头、正文和超时对上游主机做一个 HTTP 调用。
  local headers, body = request_handle:httpCall(
  "lua_cluster",
  {
    [":method"] = "POST",
    [":path"] = "/",
    [":authority"] = "lua_cluster"
  },
  "hello world",
  5000)
  -- 添加来自 HTTP 调用的信息到将要被发送到过滤器链中下一个过滤器的头。
  request_handle:headers():add("upstream_foo", headers["foo"])
  request_handle:headers():add("upstream_body_size", #body)
end

对一台上游主机做一个 HTTP 调用。调用脚本会返回headers与body。cluster 是一个字符串,映射为一个配置好的集群管理器。headers 一个要发送的键值对的表。注意,:method:path:authority 头必须被设置。body 是一个可选的要发送的正文数据的字符串。timeout 是一个整数,指定以微秒为单位的调用超时。

返回 headers,这是响应头的一个表。返回 body,这是响应正文的字符串。如果没有正文,则返回空。

有了这个方法,就为istio的扩展提供了无限可能,可以提供更复杂的业务逻辑控制,这些逻辑控制可以使用你所熟悉的任何语言,任何体系架构,只需要提供一个接口给httpCall,在httpCall调用前后,加上简单的lua逻辑代码,实现与外部授权(不光是授权,别的业务功能亦可)服务的交互对接。

实例应用

现在有这么一个需求,访问k8s apiserver时,需要进行精确的授权,如多租户及更精确的角色权限,还有创建k8s apiserver只有rolebindings,还有在创建各种k8s对象时,需要检查特定规则的labels是不合规,类似这样的场景在k8s本身提供的apiserver中比较难以做到,这都需要通过一个外围的应用进行控制。在访问k8s apiserver 时,经过istio提供的路由访问,配合httpCall,就可以调用授权服务,进行apiserver接口的各类业务控制了。

因本例子中apiserver是https,需要将https转http才能使用,详细可看我的另一往篇文章《istio的http访问https外部服务配置》,这里只贴出EnvoyFilter部分代码

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: my-auth-ef
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: HTTP_FILTER
    match:
        context: GATEWAY
        listener:
          name: 0.0.0.0_8080
          filterChain:
            filter:
              name: envoy.filters.network.http_connection_manager
              subFilter:
                name: envoy.filters.http.router
    patch:
        operation: INSERT_BEFORE
        value:
            name: envoy.filters.http.lua
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
              inlineCode: |
                  local auth_headers = {
                    [":method"] = "GET",
                    [":path"] = "/authCheck",
                    [":authority"] = "httpk8s.com"
                   }
                  local headers, body = request_handle:httpCall("lua_cluster",auth_headers,auth_body,5000)
                  --auth服务返回的是json string,这里需要JSON工具转成json对象
                  --任意找一个lua的JSON包引入或者贴到此代码的前面
                  local jBody = JSON.toJSON(body)
                  if jBody then
                        if jBody.code == 200 and jBody.token then
                                request_handle:headers():add("Authorization", jBody.token)
                                return
                        else
                                request_handle:respond({[":status"] = jBody.code},body)
                        end
                  end
                  request_handle:respond({[":status"] = 401},"Unauthorized")
                end
  - applyTo: CLUSTER
    match:
      context: ANY
      cluster: {}
    patch:
      operation: ADD
      value:
        name: lua_cluster
        connect_timeout: 0.25s
        type: STRICT_DNS
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: lua_cluster
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: my-auth.myistio.svc.cluster.local
                    port_value: 8091

注意上面的cluster的address 是authentication service的地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值