Okta authorization code example

Follow along with an example to use Okta for an authorization code to secure an httpbin app.

Before you begin

  1. Follow the get started guide to set up Gloo Gateway and deploy sample apps. You do not need to set up routing for the sample apps as you configure your gateway with an HTTPS listener as part of this guide.
  2. Make sure that the external auth service is installed and running. If not, install the external auth service in your single or multicluster environment.
    kubectl get pods -A -l app=ext-auth-service
    
  3. If you don't have an Okta account, sign up for an Okta developer account.

Step 1: Securely expose the httpbin app

Create an HTTPS listener on your gateway to securely expose the httpbin app on the httpbin-okta-auth.com hostname.

  1. Follow the steps in the HTTPS listener guide to create a virtual gateway with an HTTPS listener. When you set environment variables at the beginning of the guide, set $DNS_NAME to httpbin-okta-auth.com and $SERVER_CERT_NAME to vg-okta-auth. Make sure that you deploy the virtual gateway to the httpbin namespace. Your virtual gateway looks similar to the following:

    kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: VirtualGateway
    metadata:
      name: ${SERVER_CERT_NAME}
      namespace: httpbin
    spec:
      listeners:
      - allowedRouteTables:
        - host: $DNS_NAME
        http: {}
        port:
          number: 443
        tls:
          mode: SIMPLE
          secretName: gw-ssl-1-secret
      - allowedRouteTables:
        - host: $DNS_NAME
        http: {}
        httpsRedirect: true
        port:
          number: 80
      workloads:
      - selector:
          labels:
            istio: ingressgateway
          cluster: $CLUSTER_NAME
          namespace: gloo-mesh-gateways
    EOF
    
  2. Create a route table to route incoming HTTPS traffic on the ingress gateway to the httpbin app in your cluster.

    kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: httpbin-rt
      namespace: httpbin 
    spec:
      hosts:
      - $DNS_NAME
      http:
      - forwardTo: 
          destinations: 
          - ref: 
              name: httpbin
              namespace: httpbin
              cluster: $CLUSTER_NAME
            port: 
              number: 8000
            kind: SERVICE
        matchers:
        - uri: 
            prefix: /
            ignoreCase: true
        labels: 
          oauth: "true"
        name: httpbin
      virtualGateways:
      - name: ${SERVER_CERT_NAME}
    EOF
    
  3. Get the external address of the ingress gateway and save it as an environment variable.

    export INGRESS_GW_IP=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo $INGRESS_GW_IP
    
    export INGRESS_GW_IP=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
    echo $INGRESS_GW_IP
    

  4. Verify that you can send a request to the httpbin app.

    curl -vik --resolve httpbin-okta-auth.com:443:${INGRESS_GW_IP} https://httpbin-okta-auth.com:443/status/200
    

    Example output:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: CN=httpbin-okta-auth.com; O=vg-okta-auth
    *  start date: Jun 15 18:09:37 2023 GMT
    *  expire date: Jun 12 18:09:37 2033 GMT
    *  issuer: CN=httpbin-okta-auth.com; O=gateway-root
    *  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x146018c00)
    > GET /status/200 HTTP/2
    > Host: httpbin-okta-auth.com
    > user-agent: curl/7.77.0
    > accept: */*
    > 
    * Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
    < HTTP/2 200 
    HTTP/2 200 
    ...
    
  5. Store the URL to your httpbin app as an environment variable.

    export APP_URL=https://${DNS_NAME}
    
  6. Update the /etc/host file on your local machine to map the ingress gateway IP to the httpbin-okta-auth.com that you set up earlier. If you have an existing hostname that is configured for TLS, for example by setting up a route53 record, this step is not required.

    1. Open the /etc/hosts file.

      sudo nano /etc/hosts
      
    2. Map the value of $INGRESS_GW_IP to the httpbin-okta-auth.com hostname.

    3. Save your changes.

Step 2: Set up an Okta OIDC app

Configure an Okta OIDC app to get the client and issuer information that you need to create external auth policies.

  1. Open the Okta dashboard. If you don't have an Okta account that you can use, sign up for an Okta developer account.
  2. From the Applications menu, click Applications > Create New App. Note that you might see a Create App Integration button instead. Okta application dashboard
  3. Select OIDC - OpenID Connect as the sign-in method for your app and Web application as your application type. Then, click Next.
  4. Enter a name for your app and optionally upload a logo.
  5. Enter the sign-in redirect URL. The URL is composed of hostname that you set up for the httpbin app earlier (value of $DNS_NAME) and the /callback path. For example, if you followed the example in this guide, your redirect URL equals https://httpbin-okta-auth.com/callback.
  6. From the Assignments section, select Allow everyone in your organization to access. This way, you do not need to assign a user or group to this app. Instead, you can use your Okta developer account credentials to test the Okta authentication flow.
  7. Click Save to save your changes. You are redirected to the Okta app details page.
  8. From the General tab on the Okta app details page, note the Client ID and the client Secret. Okta General tab
  9. Store the Client ID and Secret as environment variables.
    export CLIENT_ID=<client-id>
    export CLIENT_SECRET=<secret>
    
  10. From the Sign on tab in the OpenID Connect ID Token section, change the Issuer from Dynamic to the Okta URL. Your Okta URL typically includes your account ID and an okta.com extension, such as https://dev-12345678.okta.com. Okta General tab
  11. Store the issuer URL as an environment variable.
    export ISSUER_URL=<issuer-URL>
    

Step 3: Set up external auth with Okta

Set up Gloo Platform external auth policies with Okta as the OIDC provider.

  1. Create an external auth server that enforces your extauth policy.

    kubectl apply -f - <<EOF
    apiVersion: admin.gloo.solo.io/v2
    kind: ExtAuthServer
    metadata:
      name: httpbin
      namespace: httpbin
    spec:
      destinationServer:
        port:
          number: 8083
        ref:
          cluster: $CLUSTER_NAME
          name: ext-auth-service
          namespace: gloo-mesh-addons
    EOF
    
  2. Create a Kubernetes secret with the client secret from your Okta account. Note that the client secret value is base64-encoded.

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: Secret
    type: extauth.solo.io/oauth
    metadata:
      name: okta-client-secret
      namespace: httpbin
    data:
      client-secret: $(echo -n ${CLIENT_SECRET} | base64)
    EOF
    
  3. Create an extauth policy.

    kubectl apply -f- <<EOF
    apiVersion: security.policy.gloo.solo.io/v2 
    kind: ExtAuthPolicy 
    metadata: 
      name: httpbin-okta 
      namespace: httpbin
    spec: 
      applyToRoutes: 
        - route: 
            labels: 
              oauth: "true" 
      config: 
        glooAuth: 
          configs: 
          - oauth2: 
              oidcAuthorizationCode: 
                appUrl: $APP_URL 
                callbackPath: /callback 
                clientId: $CLIENT_ID
                clientSecretRef: 
                  name: okta-client-secret 
                  namespace: httpbin 
                issuerUrl: $ISSUER_URL 
                scopes: 
                - openid 
        server: 
          name: httpbin 
    EOF
    
    Setting Description
    appUrl Enter the address to access the httpbin app. If you followed the example in this guide, your app URL is https://httpbin-okta-auth.com.
    callbackPath Create the redirect URL by appending this path to the appUrl. After successful authentication in Okta, you are redirected to this URL.
    clientId Enter the client ID that was assigned to your Okta OIDC app. You can retrieve the client ID from the General tab of your Okta OIDC app.
    clientSecret Enter the reference to the Kubernetes secret that you created earlier and that stores the client secret value. You can retrieve the client secret from the General tab of your Okta OIDC app.
    issuerUrl Enter the Okta issuer URL that you set up in the Okta app, such as https://dev-12345678.okta.com. You can retrieve the Okta issuer URL from the Issuer field on the Sign on tab of your Okta OIDC app.
  4. Make sure that the authconfig resource that is automatically created for you has a status of Accepted.

    kubectl get authconfig -n gloo-mesh-addons -o yaml
    

Step 4: Verify external auth with Okta

Try to access your app to verify that external auth is enforced by Okta.

  1. In your browser, open the app URL to your httpbin app. Make sure that you are redirected to the Okta login screen.

    open $APP_URL
    
  2. Enter your Okta developer account credentials. If successfully authenticated, Okta issues an ID token and redirects you to the httpbin app.

    Okta login screen

Cleanup

You can optionally remove the resources that you set up as part of this guide.
  1. Delete the virtual gateway, secret, and route table that you create to expose the Gloo UI.

    kubectl delete vg $SERVER_CERT_NAME -n httpbin
    kubectl delete secret gw-ssl-1-secret -n gloo-mesh-gateways
    kubectl delete rt httpbin-rt -n httpbin
    kubectl delete extauthserver httpbin -n httpbin
    kubectl delete secret okta-client-secret -n httpbin
    kubectl delete extauthpolicy httpbin-okta -n httpbin
    
  2. Remove your Okta OIDC app.

    1. Open the Okta dashboard and select Applications > Applications from the menu.
    2. Find your Okta OIDC app.
    3. Click the gear icon and from the drop-down menu, select Deactivate.