API 大使密钥授权

API key auth for Ambassador

我正在尝试弄清楚如何在 k8s 上使用 Ambassador 创建一个简单的 API 密钥保护代理,但似乎找不到任何相关文档。

具体来说,我只是想对其进行设置,以便它可以接受 API-KEY header 的请求,对其进行身份验证,如果 API-KEY 对某些客户端有效,则传递它到我的后端。

我建议您执行以下操作:

  1. 创建身份验证应用程序:对于每个受保护的端点,此应用程序将负责验证 Api 密钥。

  2. 配置 Ambassador 以将请求重定向到此服务:您只需注释您的身份验证应用程序服务定义。示例:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: auth-app
      annotations:
        getambassador.io/config: |
          ---
          apiVersion: ambassador/v1
          kind:  AuthService
          name:  authentication
          auth_service: "auth-app:8080"
          allowed_request_headers:
          - "API-KEY"
    spec:
      type: ClusterIP
      selector:
        app: auth-app
      ports:
      - port: 8080
        name: auth-app
        targetPort: auth-app
  1. auth-app 中配置一个与您要验证的应用的端点相对应的端点。假设您有一个具有如下映射的应用程序:
    apiVersion: ambassador/v1
    kind:  Mapping
    name:  myapp-mapping
    prefix: /myapp/
    service: myapp:8000

然后你需要在auth-app中有一个端点“/myapp/”。您将在那里阅读您的 API-KEY header。如果密钥有效,return HTTP 200 (OK)。然后,Ambassador 会将原始消息发送到 myapp。如果 auth-app return 除了 HTTP 200 之外还有任何其他内容,Ambassador 将 return 向客户做出响应。

  1. 在需要的应用程序中绕过身份验证。例如,您可能需要一个登录应用程序,负责向客户端提供 API 密钥。您可以在映射中使用 bypass_auth: true 来绕过这些应用程序的身份验证:
    apiVersion: ambassador/v1
    kind:  Mapping
    name:  login-mapping
    prefix: /login/
    service: login-app:8080
    bypass_auth: true

Check this 如果您想了解更多关于 Ambassador 身份验证的信息

编辑:According to this answer 如果您使用 header Authorization: Bearer {base64-API-KEY} 是一个很好的做法。在 Ambassador 中默认允许 Authorization header,所以你不需要在 allowed_request_headers 中传递它场.

在没有找到简单的方法(不涉及 spinning up an external authentication service)之后,我选择了这个快速而肮脏的解决方案。

您可以使用 Header-based Routing 并且只允许具有匹配 header:value.

的传入请求
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: protected-mapping
  namespace: default
spec:
  prefix: /protected-path/
  rewrite: /
  headers:
    # Poorman's Bearer authentication
    # Ambassador will return a 404 error unless the Authorization header value is set as below on the incoming requests.
    Authorization: "Bearer <token>"
  service: app:80

测试

# Not authenticated => 404
$ curl -sI -X GET https://ambassador/protected-path/
HTTP/1.1 404 Not Found
date: Thu, 11 Mar 2021 18:30:27 GMT
server: envoy
content-length: 0

# Authenticated => 200
$ curl -sI -X GET -H 'Authorization: Bearer eEVCV1JtUzBSVUFvQmw4eVRVM25BenJa' https://ambassador/protected-path/
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
vary: Origin
date: Thu, 11 Mar 2021 18:23:20 GMT
content-length: 15
x-envoy-upstream-service-time: 3
server: envoy

虽然从技术上讲,您可以在此处使用任何 header:value 对(例如 x-my-auth-header: header-value),但如果您想遵循标准。

在这种情况下是否对您的令牌进行 base64 编码由您决定。

以下是关于如何阅读和理解这方面规范的详细说明:

归结为令牌值的以下正则表达式格式:

[-a-zA-Z0-9._~+/]+=*