【问题标题】:API key auth for Ambassador大使的 API 密钥身份验证
【发布时间】:2019-09-04 18:17:00
【问题描述】:

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

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

【问题讨论】:

    标签: authentication kubernetes api-gateway


    【解决方案1】:

    我建议您执行以下操作:

    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 标头。如果密钥有效,则返回 HTTP 200(OK)。然后大使会将原始消息发送到 myapp。如果 auth-app 返回 HTTP 200 以外的任何其他内容,Ambassador 会将该响应返回给客户端。

    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},这是一个很好的做法。在 Ambassador 中,默认情况下允许 Authorization 标头,因此您无需在 allowed_request_headers 字段中传递它。

    【讨论】:

    • 这是否意味着Ambassador 自己不做任何API 密钥检查,而我总是需要为此提供额外的服务?
    • 在开源版本的情况下,是的,唯一的身份验证方法是通过外部服务。我的开发团队对此也感到失望,但在开发了额外的服务之后,我们享受了创建自己的规则和身份验证机制的灵活性,每个端点可能会有所不同。根据付费版本Ambassador Pro 页面,该版本集成了 OAuth、JWT 验证和即将推出的 API 密钥功能。专业版是相当新的,所以我认为大多数大使用户都可以通过外部身份验证。
    【解决方案2】:

    在没有找到简单的方法(不涉及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._~+/]+=*
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 2021-02-10
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      相关资源
      最近更新 更多