大使的API密钥验证

时间:2019-04-14 16:53:47

标签: authentication kubernetes api-gateway

我正在尝试找出如何在k8s上与Ambassador创建一个受API密钥保护的简单代理,但似乎找不到任何文档。

具体地说,我只想设置它,以便它可以使用带有API-KEY标头的请求进行身份验证,并且如果API-KEY对于某些客户端有效,则将其传递到我的后端。

2 个答案:

答案 0 :(得分:2)

我建议您执行以下操作:

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

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

    ---
    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 中配置与您要认证的应用程序的端点相对应的端点。假设您有一个带有这样的Mapping的应用程序:
    apiVersion: ambassador/v1
    kind:  Mapping
    name:  myapp-mapping
    prefix: /myapp/
    service: myapp:8000

然后,您需要在 auth-app 中具有终结点“ / myapp / ”。您将在此处阅读 API-KEY 标头。如果密钥有效,则返回HTTP 200(确定)。然后,大使将原始消息发送到 myapp 。如果 auth-app 返回HTTP 200以外的任何其他内容,大使将将该响应返回给客户端。

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

Check this,如果您想进一步了解大使身份验证

编辑:According to this answer,如果您用作标题Authorization: Bearer {base64-API-KEY},则是一个好习惯。在大使中,默认情况下允许使用 Authorization 标头,因此您无需在 allowed_request_headers 字段中传递它。

答案 1 :(得分:1)

在没有找到简单的方法(不涉及 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),但如果您想遵循标准,Authorization: Bearer ... 方案似乎是 best option

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

以下是有关如何阅读和理解这方面规范的冗长解释:https://stackoverflow.com/a/56704746/4550880

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

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