All Products
Search
Document Center

Alibaba Cloud Service Mesh:Implement custom authorization by using the HTTP protocol

Last Updated:Feb 04, 2024

The custom authorization feature allows you to perform fine-grained Resource Access Management (RAM) on services that use the HTTP protocol. With this feature, you can customize authorization mechanisms based on your business requirements. Authentication is required when services communicate with each other. This ensures that only authenticated and authorized requests can access specific service resources and improves the security of service-to-service communication. This topic uses the httpbin application and the sleep application in the following example to describe how to implement custom authorization by using the HTTP protocol.

Prerequisites

A Container Service for Kubernetes (ACK) cluster is added to your ASM instance. For more information, see The cluster is added to the ASM instance.

Step 1: Deploy a custom authorization service

Deploy a custom authorization service in the ACK cluster. This service must comply with the API specifications of Istio for custom authorization services and support the HTTP and gRPC protocols. This service is used to implement custom authorization. The sample authorization service provided in this topic specifies that only requests with the x-ext-authz: allow header can pass the authentication.

Note

You can use the following sample authorization service or create a custom authorization service based on the code of the sample authorization service. For more information, visit the GitHub website.

  1. Use kubectl to connect to the cluster and use the following content to create an ext-authz.yaml file.

    For more information about how to use kubectl to connect to the cluster, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.

    Expand to view the ext-authz.yaml file

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    # Example configurations for deploying ext-authz server separately in the mesh.
    
    apiVersion: v1
    kind: Service
    metadata:
      name: ext-authz
      labels:
        app: ext-authz
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 8000
      - name: grpc
        port: 9000
        targetPort: 9000
      selector:
        app: ext-authz
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ext-authz
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ext-authz
      template:
        metadata:
          labels:
            app: ext-authz
        spec:
          containers:
          - image: istio/ext-authz:0.6
            imagePullPolicy: IfNotPresent
            name: ext-authz
            ports:
            - containerPort: 8000
            - containerPort: 9000
    ---
  2. Run the following command to deploy the custom authorization service in the cluster:

    kubectl apply -f ext-authz.yaml
  3. Run the following command to query the status of the pod in which the custom authorization service resides:

    kubectl get pod

    Expected output:

    NAME                         READY   STATUS    RESTARTS   AGE
    ext-authz-6b5db88f86-2m7c6   2/2     Running   0          79m
  4. Run the following command to check whether the ext-authz application works as expected:

    kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz

    Expected output:

    2023/12/20 08:15:39 Starting gRPC server at [::]:9000
    2023/12/20 08:15:39 Starting HTTP server at [::]:8000

    If the preceding result is returned, the custom authorization service is deployed.

  5. Obtain the HTTP port that is used by the ext-authz service.

    1. Log on to the ACK console. In the left-side navigation pane, click Clusters.

    2. On the Clusters page, click the name of the cluster that you want to manage and choose Network > Services in the left-side navigation pane.

    3. On the Services page, click ext-authz.

      In the Endpoint section of the service details page, you can view the HTTP port. In this example, the port is 8000. The HTTP address that is used to access the custom authorization service is ext-authz.default.svc.cluster.local:8000.

Step 2: Deploy sample applications

  1. Create an httpbin.yaml file that contains the following content:

    Expand to view the httpbin.yaml file

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # httpbin service
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: httpbin
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
        service: httpbin
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 80
      selector:
        app: httpbin
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpbin
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpbin
          version: v1
      template:
        metadata:
          labels:
            app: httpbin
            version: v1
        spec:
          serviceAccountName: httpbin
          containers:
          - image: docker.io/kennethreitz/httpbin
            imagePullPolicy: IfNotPresent
            name: httpbin
            ports:
            - containerPort: 80
                            
  2. Run the following command to deploy the httpbin application in the cluster:

    kubectl apply -f httpbin.yaml
  3. Create a sleep.yaml file that contains the following content:

    Expand to view the sleep.yaml file

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # Sleep service
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: curlimages/curl
            command: ["/bin/sleep", "3650d"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
    ---
                            
  4. Run the following command to deploy the sleep application in the cluster:

    kubectl apply -f sleep.yaml

Step 3: Use the HTTP protocol to connect to the custom authorization service

Declare the custom authorization service that you deployed in Step 1 in the ASM instance. This way, the ASM instance can use the service to authenticate requests.

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Mesh Security Center > Custom Authorization Service. On the page that appears, click Define Custom Authorization Service.

  3. On the Register Custom Authorization Service page, click the Custom authorization service (HTTP or gRPC protocol) implemented based on envoy.ext_authz tab, configure the related parameters, and then click Create.

    Type

    Parameter

    Description

    Required parameters

    Protocol

    The protocol that is used by the custom authorization service. In this example, HTTP is selected.

    Name

    The name of the custom authorization service. In this example, the value is set to test4http.

    Service Address

    The endpoint of the custom authorization service. The format is <Service name>.<Namespace>.svc.<Domain name of the cluster>. The names must be full names. In this example, the value is set to ext-authz.default.svc.cluster.local.

    Port(1 - 65535)

    The service port of the custom authorization service. In this example, the value is set to 8000.

    Timeout(second)

    The period of time during which the authentication result must be returned. Unit: seconds. If the custom authorization application fails to respond within this period of time, the service is considered unavailable. In this example, the value is set to 10.

    Optional parameters

    Skip authentication while authorization service is unavailable

    Specifies whether to allow requests when the custom authorization service is unavailable. If you turn on this switch, requests are allowed when the custom authorization service is unavailable. In this example, the switch is turned off.

    Error code returned by asm proxy while Auth-Service is not available

    The error code to return when the custom authorization service is unavailable. This parameter is available only if you turn off Skip authentication while authorization service is unavailable. If you turn on Error code returned by asm proxy while Auth-Service is not available, you must specify an error code. This way, ASM returns this error code to the caller when the custom authorization service is unavailable. In this example, the switch is turned off.

    Carry origin header within auth request

    Specifies whether to include the specified client request headers in the authentication request sent to the custom authorization service. If you turn on this switch, you must specify one or more header keys. Then, ASM adds the specified headers that are found in the client request to the authentication request sent to the custom authorization service. The settings in this example are shown in Carry headers in an authentication request.

    Note

    This parameter is available only if you set the Protocol parameter to HTTP.

    Add a header in the authentication request

    Specifies whether to include additional headers in the authentication request sent to the custom authorization service. If you turn on this switch, you must specify one or more header keys and values. Then, ASM adds the header keys and values to the authentication request sent to the custom authorization service.

    If a header with the same header key already exists in the client request, the original header value will be overwritten. In this example, the switch is turned off.

    Note

    This parameter is available only if you set the Protocol parameter to HTTP.

    Overwrite Header when authentication passes

    Specifies whether to overwrite the specified headers in the client request sent to the upstream if the authentication is successful. If you turn on this switch, you must specify one or more header keys. If the authentication is successful, ASM overwrites the specified headers in the client request with the headers returned in the authentication response. The settings in this example are shown in Overwrite headers when authentication passes.

    Note

    This parameter is available only if you set the Protocol parameter to HTTP.

    Overwrite Header when authentication fails

    Specifies whether to overwrite the specified headers in the response sent to the caller if the authentication fails. If you turn on this switch, you must specify one or more header keys. If the authentication fails, ASM overwrites the headers in the response sent to the caller with the specified headers in the authentication response. The settings in this example are shown in Overwrite headers when authentication fails.

    Note

    This parameter is available only if you set the Protocol parameter to HTTP.

    Carry origin request body within auth request

    Specifies whether to include the client request body in the authentication request sent to the custom authorization service. If you turn on this switch, you must specify the maximum length of the request body. If you also turn on Allow send incomplete message to Auth-Service, ASM truncates the request body if the length of the request body exceeds the maximum length. Then, ASM sends the authentication request with the truncated request body to the custom authorization service.

    Figure 1. Carry headers within an authentication request

    Note

    The last line x-ext-authz is a new header added to the request.

    在鉴权请求中携带Header

    Figure 2. Overwrite headers when authentication passes

    Note

    The last line x-ext-authz-check-result is a new header added to the request.

    鉴权通过时覆盖Header

    Figure 3. Overwrite headers when authentication fails

    Note

    The last line x-ext-authz-check-result is a new header added to the request.

    鉴权失败时覆盖Header

Step 4: Create an authorization policy for the ASM instance

Create an authorization policy to configure the request operation that requires authentication.

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy. On the page that appears, click Create.

  3. On the Create page, configure the relevant parameters and click Create.

    Parameter

    Description

    Name

    The name of the custom authorization policy. In this example, the value is set to test1.

    Policy Type

    The type of the custom authorization policy. In this example, the value is set to Custom Authorization Service.

    Custom Authorization Service

    In this example, httpextauth-test4http(HTTP) is selected.

    Namespace

    The namespace in which the authorization policy resides. On the Workload Scope tab, select default from the Namespace drop-down list.

    Effective Scope

    The effective scope of the authorization policy. In this example, the value is set to Service.

    Workload

    The workload on which the authorization policy takes effect. In this example, the value is set to httpbin.

    Request Matching Rules

    The destination path of requests. In this example, Paths is turned on in the Add Request Target section and the value is set to /headers.

Step 5: Verify that the custom authorization service takes effect

  1. Run the following command to access httpbin.default:8000/ip:

    kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/ip" -s -o /dev/null -w "%{http_code}\n"

    The status code 200 is returned, which indicates that custom authorization is not triggered. The reason is that the path contains /ip instead of /headers defined in the authorization policy.

  2. Run the following command to use a request with the x-ext-authz: deny request header to access httpbin.default:8000/headers:

    kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -ndefault -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: deny" -s -i

    Expected output:

    HTTP/1.1 403 Forbidden
    x-ext-authz-check-result: denied
    content-length: 76
    content-type: text/plain; charset=utf-8
    date: Wed, 20 Dec 2023 09:53:28 GMT
    server: envoy
    x-envoy-upstream-service-time: 10
    
    denied by ext_authz for not found header `x-ext-authz: allow` in the request

    The preceding result indicates that custom authorization is triggered but the authentication fails. The returned result contains the newly-added response header x-ext-authz-check-result: denied. The reason why authorization is triggered is that the path contains /headers defined in the authorization policy.

  3. Run the following command to use a request with the x-ext-authz: allow request header to access httpbin.default:8000/headers:

    kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: allow" -s

    Expected output:

    {
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin.default:8000",
        "User-Agent": "curl/8.5.0",
        "X-Envoy-Attempt-Count": "1",
        "X-Ext-Authz": "allow",
        "X-Ext-Authz-Check-Result": "allowed",
        "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=c3e5364e87add0f4f69e6b0d029f5961b404c8f209bf9004b3d21a82cf67****;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
      }
    }

    The preceding result indicates that custom authorization is triggered and the authentication is successful. The returned result contains the newly-added response header "X-Ext-Authz-Check-Result": "allowed". The reason why authorization is triggered is that the path contains /headers defined in the authorization policy.

References