Account login OAuth with Google

You can use Gloo Mesh external auth to authenticate users to your apps with other accounts that they have. In this guide, you set up Gloo Mesh to authenticate with users’ Google accounts. You can adapt these steps for other identity providers, such as Microsoft or Apple.

Before you begin

  1. Complete the demo setup to install Gloo Mesh, Istio, and Bookinfo in your cluster.

  2. Create the Gloo Mesh resources for this policy in the management and workload clusters.

    The following files are examples only for testing purposes. Your actual setup might vary. You can use the files as a reference for creating your own tests.

    1. Download the following Gloo Mesh resources:

    2. Apply the files to your management cluster.

      kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-1.yaml --context ${MGMT_CONTEXT}
      kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-2.yaml --context ${MGMT_CONTEXT}
      kubectl apply -f workspace_gloo-mesh_anything.yaml --context ${MGMT_CONTEXT}
      
    1. Download the following Gloo Mesh resources:

    2. Apply the files to your workload cluster.

      kubectl apply -f virtual-gateway_bookinfo_north-south-gw.yaml --context ${REMOTE_CONTEXT1}
      kubectl apply -f workspace-settings_bookinfo_anything.yaml --context ${REMOTE_CONTEXT1}
      
  3. Send a request to verify that you can reach the ratings app without authorization. By default Gloo Mesh allows any request on routes that do not specify authentication.

    curl -v ${INGRESS_GW_IP}/ratings/1 -H "Host: www.example.com"
    

    Example output:

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

Register your app with Google

To use Google as an identity provider (IdP), you must register your app with the Google API.

  1. Log in to the Google Developer Console.
  2. Optional: For first-time users, or to separate your resources from others in your cloud, create a project.
  3. Configure your OAuth consent screen details. If you have an existing consent screen that you want to use, skip to the next step.
    1. From the menu, click OAuth consent screen.
    2. Select the Internal user type, and click Create.
    3. From the OAuth consent screen tab, enter the details of your app.
      • In the App information section, enter a name and email for your app.
      • You can skip the App domain and Authorized domain sections.
      • In the Developer contact information section, enter your email.
      • Click Save and continue.
    4. Optional: From the Scopes tab, you can restrict permissions to particular APIs in your app. For testing purposes, you can skip this section. Click Save and continue.
    5. Review the summary and click Back to dashboard.
  4. Create the credentials to use Google as an OAuth client.
    1. From the menu, click Credentials.
    2. From the Credentials menu bar, click + Create credentials, and then OAuth client ID.
    3. From the Application type dropdown, select Web application. You can optionally rename the client.
    4. In the Authorized redirect URIs section, click + Add URI.
    5. Enter the following URI for demonstration purposes: http://localhost:8080/callback
    6. Click Create.
  5. Store the Client ID and Client secret values as environment variables. You can also download the client information as a JSON file.
    export CLIENT_ID=<client-id>
    export CLIENT_SECRET=<client-secret>
    

Configure an OAuth policy

Create the external auth policy that uses Google as an identity provider.

You can do the following steps in a different order, depending on when you want the policy to take effect. For example, you might want the policy to always take effect as soon as the route is created. To do so, you can create the policy before you add the route to the route table.
  1. Store the client secret as a Kubernetes secret in the workload cluster that you want to create the external auth policy in.

    kubectl apply --context ${REMOTE_CONTEXT1} -f - <<EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: google
      namespace: bookinfo
    type: extauth.solo.io/oauth
    data:
      client-secret: $(echo -n ${CLIENT_SECRET} | base64)
    EOF
    
  2. Create an external auth server to use for your policy.

    kubectl --context ${REMOTE_CONTEXT1} apply -f - <<EOF
    apiVersion: admin.gloo.solo.io/v2
    kind: ExtAuthServer
    metadata:
      name: ext-auth-server
      namespace: bookinfo
    spec:
      destinationServer:
        ref:
          cluster: cluster-1
          name: ext-auth-service
          namespace: gloo-mesh
        port:
          name: http2
    EOF
    
  3. Create a route table for the ratings app and external auth policy. Note that the route table selects the virtual gateway that you created before you began, and routes to the ratings service.

    kubectl --context ${REMOTE_CONTEXT1} apply -f - <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: bookinfo
      namespace: bookinfo
      labels:
        expose: "true"
    spec:
      hosts:
        - '*'
      virtualGateways:
        - name: north-south-gw
          namespace: bookinfo
          cluster: cluster-1
      workloadSelectors: []
      http:
        - name: ratings
          labels:
            oauth: "true"
          matchers:
          - uri:
              exact: /ratings/1
          - uri:
              prefix: /callback
          forwardTo:
            destinations:
            - ref:
                name: ratings
                namespace: bookinfo
    EOF
    
  4. Create an external auth policy that uses Google for OIDC.

    kubectl --context ${REMOTE_CONTEXT1} apply -f - <<EOF
    apiVersion: security.policy.gloo.solo.io/v2
    kind: ExtAuthPolicy
    metadata:
      name: ratings-google
      namespace: bookinfo
    spec:
      applyToRoutes:
      - route:
          labels:
            oauth: "true"
      config:
        server:
          name: ext-auth-server
          namespace: bookinfo
          cluster: cluster-1
        glooAuth:
          configs:
          - oauth2:
              oidcAuthorizationCode:
                appUrl: http://localhost:8080
                callbackPath: /callback
                clientId: ${CLIENT_ID}
                clientSecretRef:
                  name: google
                  namespace: bookinfo
                issuerUrl: https://accounts.google.com
                scopes:
                - email
                session:
                  cookieOptions:
                    noteSecure: true
                headers:
                  idTokenHeader: jwt
    EOF
    

Review the following table to understand this configuration. For more information, see the API reference.

Setting Description
applyToRoutes Configure which routes to apply the policy to, by using labels. The label matches the app and the route from the route table. If omitted, the policy applies to all routes in the workspace.
server The external auth server to use for the policy.
oauth2 Configure the OAuth 2.0 protocol details to use to authenticate requests. The example uses Google as the external identity provider.
appUrl The public URL of the app that you want to set up external auth for. This setting is used in combination with the callbackPath attribute. In this example, you did not configure Google OAuth with a public URL. Instead, you can use http://localhost:8080 to test the authentication setup.
callbackPath The callback path, relative to the appUrl setting. After a user authenticates, the identity provider redirects the user to this callback URL. Gloo Mesh intercepts requests with this path, exchanges the authorization code received from the IdP for an ID token, places the ID token in a cookie on the request, and forwards the request to its original destination.
The callback path must have a matching route in the route table that is associated with the external auth policy. For example, you could simply have a / path-prefix route which would match any callback path. The important part of this callback “catch all” route is that the request goes through the routing filters including external auth.
clientId The client ID token that you got when you registered your app with the identity provider. In this example, you set the client ID in an earlier step.
clientSecretRef The Kubernetes secret that has the client secret that you got when you registered your app with the identity provider. In this example, you created the secret in an earlier step.
issuerUrl The URL of the OpenID Connect identity provider. Gloo Mesh automatically discovers OIDC configuration by querying the .well-known/openid-configuration endpoint on the issuer_url. In this example, Gloo Mesh expects to find OIDC discovery information at https://accounts.google.com.
scopes Other OIDC scopes to request. By default, the openid scope is included, which returns the OIDC protocol information that is needed to verify the user's identity. This example also requests the email scope, which has the user's Google email address. For more information, see the OpenID docs.
session Details on how to store the user session details. In this example, the cookie is insecure, for demonstration purposes.
idTokenHeader The header name to use to forward the ID token. This example sets the header name to jwt.

Verify the OAuth policy

  1. Enable port-forwarding of the ingress gateway so that you can reach your apps on the local host. You can store the port-forward process ID as an environment variable so that you can end the process later.

    kubectl port-forward --context ${REMOTE_CONTEXT1} -n istio-system deploy/istio-ingressgateway 8080 &
    portForwardPid=$!
    
  2. In your web browser, open the path to your application. You are redirected to the authentication page from the Google identity provider.

    open http://localhost:8080/ratings/1
    
  3. Enter your user credentials from Google.

    Google login page

    Example output: Gloo Mesh redirects you to the /callback page, with the information from Google added as a query string in the URL.

    Callback URL

Cleanup

You can clean up the external auth policy that you created in this guide by running the following commands.

kill $portForwardPid1
kubectl delete --context ${REMOTE_CONTEXT1} extauthpolicy -n bookinfo ratings-google