请求认证(Request Authentication)

请求认证定义工作负载支持哪些请求身份验证方法。网关或Sidecar会根据配置的认证规则对请求进行认证。如果请求携带了非法的认证信息,则会被拒绝。一个请求如果没有包含任何认证信息也会通过认证,但不会获得认证过后的合法身份。如果要限制仅允许经过认证的请求通过,需要配合AuthorizationPolicy实现。本文介绍请求认证的配置示例和字段说明。

配置示例

示例一:限制所有httpbin的工作负载收到的请求必须携带JWT

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: "issuer-foo"
    jwksUri: https://example.com/.well-known/jwks.json
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  rules:
  - from:
    - source:
        requestPrincipals: ["*"]

示例二:限制default命名空间下的工作负载收到的请求必须携带JWT

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: req-authn-for-all
  namespace: default
spec:
  jwtRules:
  - issuer: "issuer-foo"
    jwksUri: https://example.com/.well-known/jwks.json
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-jwt-for-all
  namespace: default
spec:
  rules:
  - from:
    - source:
        requestPrincipals: ["*"]

示例三:对于不同的Host允许携带不同的JWT

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: "issuer-foo"
  - issuer: "issuer-bar"
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  rules:
  - from:
    - source:
        requestPrincipals: ["issuer-foo/*"]
    to:
    - operation:
        hosts: ["example.com"]
  - from:
    - source:
        requestPrincipals: ["issuer-bar/*"]
    to:
    - operation:
        hosts: ["another-host.com"]

示例四:提取JWT payload并添加至请求头中

本示例将JWT payload中的foo声明提取并添加至请求头x-jwt-claim-foo中。

apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
  name: "jwt-example"
  namespace: foo
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: "issuer-foo"
    jwksUri: "https://example.com/.well-known/jwks.json"
    outputClaimToHeaders:
    - header: "x-jwt-claim-foo"
      claim: "foo"

字段说明

RequestAuthentication

字段

类型

是否必须

说明

selector

WorkloadSelector

定义在当前命名空间中哪些工作负载应用当前配置。如果该配置存在于根命名空间(istio-system),selector将会匹配所有命名空间中的工作负载。如果未配置,selector将匹配到所有工作负载。

jwtRules

JWTRule[]

定义一个JWT规则列表,用于在指定工作负载上使用JWT规则进行验证。后续请求的有效身份将会从JWT中获取。只有当JWT出现在请求的指定位置时才会触发指定的规则。根据JWTRule中的配置对JWT进行验证时,如果验证失败,请求会被拒绝。

重要

不支持一个请求在多个位置携带不同的TOKEN。此类请求身份是未定义的。

targetRefs

PolicyTargetReference[]

targetRefs指定了当前策略要在哪些资源上生效。

当前支持填写以下资源:

  • 同一命名空间下引用Gateway(Gateway API)。

    • group: gateway.networking.k8s.io

    • kind: Gateway

  • 在根命名空间下引用GatewayClass。

    • group: gateway.networking.k8s.io

    • kind: GatewayClass

  • 同一命名空间下的Service。仅在Waypoint上支持。

    • group: ""或者group: "coore"

    • kind: Service

  • 同一命名空间下的ServiceEntry。

    • group: networking.istio.io

    • kind: ServiceEntry

当策略需要应用在Waypoint上时,必须使用此字段。

如果没有设置当前字段,则生效范围由selector字段决定。selectortargetRefs只能定义一个。

JWTRule

JWT(JSON Web Token)用于身份验证,由RFC 7519定义。关于如何在认证流程中使用JWT,请参见OAuth 2.0OIDC 1.0

JWT示例

说明

issuer: https://example.com
audiences:
- bookstore_android.apps.example.com
  bookstore_web.apps.example.com

JWT需要https://example.com签发,并且audiences应为bookstore_android.apps.example.com或者bookstore_web.apps.example.com。Token应在默认的授权Header中。JWKS(JSON Web Key Set)将按照OpenID Connect协议被发现。

issuer: https://example.com
fromHeaders:
- "x-aliyun-asm-jwt"

表示一个不在默认位置的Token。本示例Tokenx-aliyun-asm-jwt Header中。

字段

类型

是否必须

说明

issuer

string

指定JWTIssuer(签发者)。具有不同IssuerJWT将会被拒绝。

audiences

string[]

JWTaudiences列表,表示允许这些audiences访问网格内的应用,否则将拒绝该请求。如果audiences为空,则不限制请求的audiences

jwks

string

用于JWTJWKS。

fromHeaders

JWTHeader[]

期望JWT存在于哪些Header中。以下示例表示期望从x-jwt-assertion Header中获取JWT,且JWT存在于Bearer 之后。

  fromHeaders:
  - name: x-jwt-assertion
    prefix: "Bearer "

fromParams

string

期望JWT存在于哪些请求参数中。以下示例表示期望能通过my_token参数传递JWT。

  fromParams:
  - "my_token"
重要

当前不支持请求在不同的位置携带不同的JWT,否则请求的principal将是未定义的。

outputPayloadToHeader

string

指定一个Header名称。如果一个JWT验证成功,验证过的信息将被传递给上游服务。转发的数据是经过 Base64 编码的JWT负载(JSON 格式)。如果未指定,则不会添加该Header。

forwardOriginalToken

bool

默认为false。取值说明如下。

  • true:表示在转发给上游服务的请求中保留原始的JWT。

  • false:表示在转发给上游服务的请求中不会保留原始的JWT。

outputClaimToHeaders

ClaimToHeader[]

此字段指定了一系列操作,用于在成功验证 jwt token 后将 jwt claim 复制到 HTTP 头。与 output_payload_to_header 不同,它允许输出单个 jwt claim 而非整个有效 jwt payload。列表中每个操作指定的 HTTP 头必须唯一。同时也支持字符串/整数/布尔类型的嵌套声明。

outputClaimToHeaders:
  - header: x-my-company-jwt-group
    claim: my-group
  - header: x-test-environment-flag
    claim: test-flag
  - header: x-jwt-claim-group
    claim: nested.key.group

ClaimToHeader

该结构体指定了将 jwt claim 复制到请求 header 的详细规则。

字段

类型

是否必须

说明

header

string

要创建的请求头名称。如果请求中已存在该头部,则会被覆盖。

claim

string

要复制的jwt claim名称。仅支持String/Int/Bool类型的声明。如果声明不存在或声明类型不受支持,则不会创建该头部。

JWTHeader

指定JWT所在的Header信息。

字段

类型

是否必须

说明

name

string

HTTP Header的名称。

prefix

string

用于在请求中寻找Token。在解码Token之前,网关或Sidecar会去除这个前缀。例如

Authorization: “Bearer xxxxxxxxxx”,这个Header需要配置的prefix应为Bearer (末尾有空格),不能是Bearer(末尾无空格)。