Basic auth

This feature is available with a Gloo Mesh Gateway license only.

In certain cases - such as during testing or when releasing a new API to a small number of known users - it may be convenient to secure gateway routes using Basic Authentication. With this simple authentication mechanism the encoded user credentials are sent along with the request in a standard header.

To secure your routes using basic authentication, you first need to provide Gloo Mesh Gateway with a set of known users and their passwords. You can then use this information to decide who is allowed to access which routes. If a request matches a route on which basic authentication is configured, Gloo Mesh Gateway will verify the credentials in the standard Authorization header before sending the request to its destination. If the user associated with the credentials is not explicitly allowed to access that route, Gloo Mesh Gateway will return a 401 response to the downstream client.

Before you begin

External auth for north-west traffic requires at least Gloo Mesh Enterprise version 1.1, including the Gloo Mesh Gateway license.

  1. Install Gloo Mesh Enterprise with the external authentication feature enabled.

  2. Install the Istio Bookinfo sample application.

  3. Confirm that your workstation has tools to generate hashed, salted passwords, such as htpasswd, and to encode strings, such as base64.

Creating a Virtual Gateway

Configure Gloo Mesh Gateway to route requests to the Bookinfo app by using a VirtualGateway custom resource to match all requests that:

Apply the following virtual gateway and auth config:

apiVersion: networking.enterprise.mesh.gloo.solo.io/v1beta1
kind: VirtualGateway
metadata:
  labels:
    app: bookinfo-policies
    app.kubernetes.io/name: bookinfo-policies
  name: test-inlined-gateway
  namespace: bookinfo
spec:
  connectionHandlers:
    - http:
        routeConfig:
          - virtualHost:
              domains:
                - www.example.com
              routes:
                - matchers:
                    - uri:
                        prefix: /ratings
                  name: ratings
                  options: {}
                  routeAction:
                    destinations:
                      - kubeService:
                          clusterName: mgmt.cluster
                          name: ratings
                          namespace: bookinfo
  ingressGatewaySelectors:
    - destinationSelectors:
        - kubeServiceMatcher:
            clusters:
              - mgmt.cluster
            labels:
              istio: ingressgateway-ns
            namespaces:
              - istio-system
      portName: http2

Securing the route

By default, Gloo Mesh Enterprise allows requests to destinations without requiring authentication. You can change the default behavior and use external auth to require credentials for ingress routes.

  1. Send a request to the ratings destination.

    curl -v $(BOOKINFO_INGRESS_GATEWAY_URL)/ratings/1 -H "Host: www.example.com"
    

    Notice that in the output, you are able to reach the destination without having to provide any credentials.

    {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
    
  2. Update the virtual gateway for the ratings destination so that only requests by the user user with password password are allowed. Gloo Mesh expects the password to be hashed and salted using the APR1 format. Passwords in this format follow this pattern: $apr1$**SALT**$**HASHED_PASSWORD**.

    htpasswd -nbm user password
    

    Example output: user:$apr1$TYiryv0/$8BvzLUO9IfGPGGsPnAgSu1, where:

    • TYiryv0/ is the salt and
    • 8BvzLUO9IfGPGGsPnAgSu1 is the hashed password.
  3. Create an AuthConfig custom resource and update the VirtualGateway custom resource to refer to the AuthConfig.

apiVersion: networking.enterprise.mesh.gloo.solo.io/v1beta1
kind: VirtualGateway
metadata:
  labels:
    app: bookinfo-policies
    app.kubernetes.io/name: bookinfo-policies
  name: test-inlined-gateway
  namespace: bookinfo
spec:
  connectionHandlers:
    - http:
        routeConfig:
          - virtualHost:
              domains:
                - www.example.com
              routes:
                - matchers:
                    - uri:
                        prefix: /ratings
                  name: ratings
                  options:
                    extauth:
                      configRef:
                        name: basic-auth
                        namespace: bookinfo
                  routeAction:
                    destinations:
                      - kubeService:
                          clusterName: mgmt.cluster
                          name: ratings
                          namespace: bookinfo
  ingressGatewaySelectors:
    - destinationSelectors:
        - kubeServiceMatcher:
            clusters:
              - mgmt.cluster
            labels:
              istio: ingressgateway-ns
            namespaces:
              - istio-system
      portName: http2
---
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
  labels:
    app: bookinfo-policies
    app.kubernetes.io/name: bookinfo-policies
  name: basic-auth
  namespace: bookinfo
spec:
  configs:
    - basicAuth:
        apr:
          users:
            user:
              hashedPassword: 8BvzLUO9IfGPGGsPnAgSu1
              salt: TYiryv0/

Your destination is set up to deny unauthenticated requests! Now for a request to be allowed, the request must include the user credentials inside the expected header in the following format.

Authorization: basic <base64_encoded_credentials>

Continue to the next section to test out the authentication.

Testing authentication for requests

  1. Resend the previous request.

    kubectl exec $(kubectl get pod -l app=productpage -A  -o jsonpath='{.items[0].metadata.name}') --namespace=bookinfo -c    productpage -- curl -sS reviews:9080/reviews 
    

    Notice that the response now contains a 401 Unauthorized code, indicating that Gloo Mesh denied the request.

       > GET /posts/1 HTTP/1.1
       > Host: foo
       > User-Agent: curl/7.54.0
       > Accept: */*
       >
       < HTTP/1.1 401 Unauthorized
       < www-authenticate: Basic realm=""
       < date: Mon, 07 Oct 2019 13:36:58 GMT
       < server: envoy
       < content-length: 0
       
  2. Encode the user user and password password in base64 so that you can test an authenticated request.

    echo -n "user:password" | base64
    

    Example output:

    dXNlcjpwYXNzd29yZA==
    
  3. Include the encoded credentials in the header of your request.

    curl -v $(BOOKINFO_INGRESS_GATEWAY_URL)/ratings/1 -H "Host: www.example.com" -H "Authorization: basic dXNlcjpwYXNzd29yZA=="
    

    You can reach the ratings service again!

    {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
    

Logging

View the ext-auth-service deployment logs to verify that the AuthConfig was set up succesfully.

kubectl logs -n gloo-mesh deploy/ext-auth-service -c ext-auth-service -f

In the example output, notice the got new config success message.

"logger":"extauth","caller":"runner/run.go:179","msg":"got new config"

Summary

In this tutorial, you installed Gloo Mesh Enterprise with external auth enabled, created a basic authentication AuthConfig, and configured a VirtualGateway to use the AuthConfig to secure requests that are routed to your app.

To clean up the resources that you created, run the following commands.

kubectl delete ac -n bookinfo basic-auth
kubectl delete vg -n bookinfo test-inlined-gateway