When users open the host of your frontend portal, such as portal.example.com, they can log in. By logging in, users can take advantage of the portal’s self-service feature to join teams, create apps, subscribe their apps to the ApiProducts in the portal, and generate OIDC or API key credentials to access the ApiProducts.

Before you begin

  1. Complete the tutorial to set up Gloo Portal.
  2. Complete the tutorial to Create a Portal.

Step 1: Set up the IdP

You can use an IdP to enforce authentication for several use cases in Gloo Portal, such as protecting APIs with external auth policies, the portal frontend app, and IdP Connect. It is recommended to use the same IdP for all your Gloo Portal use cases. The following IdPs have been successfully set up with Portal: Amazon Cognito and Keycloak. If you use another IdP, you might need to modify the steps for your setup.

For instructions, follow the Set up an IdP guide. The guide uses Keycloak as an example. You can adjust these steps for other IdPs.

Step 2: Set up portal

Before you began, you completed a tutorial to set up a basic portal, including backend and frontend routes. Now, you must update the portal for the login feature.

  1. Verify that you have an HTTPRoute that maps the /v1 path to the backend portal server. If you do not, create the HTTPRoute.

    Example command to check existing HTTPRoutes:

      kubectl get HTTPRoutes -n gloo-system
      

    Example command to create a backend HTTPRoute:

      kubectl apply -n gloo-system -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: portal-backend-route
      namespace: gloo-system
    spec:
      parentRefs:
        - name: http
          namespace: gloo-system
      hostnames:
        - portal.example.com
        - gateway-portal-web-server.gloo-system
      rules:
        - backendRefs:
            - name: gateway-portal-web-server
              namespace: gloo-system
              port: 8080
          matches:
          - path:
              type: PathPrefix
              value: /v1
    EOF
      
  2. Update the HTTPRoute for the frontend portal to add the /v1 path for the login and logout routes. Note that if you use a different hostname for the backend than for the frontend, you must create a CORS policy.

      kubectl apply -n gloo-system -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: portal-frontend-route
      namespace: gloo-system
    spec:
      parentRefs:
        - name: http
          namespace: gloo-system
      hostnames:
        - portal.example.com
        - gateway-portal-web-server.gloo-system
      rules:
        - backendRefs:
            - name: portal-frontend
              namespace: gloo-system
              port: 4000
          matches:
          - path:
              type: PathPrefix
              value: /
     - backendRefs:
         - name: portal-frontend
           namespace: gloo-system
           port: 4000
       matches:
       - path:
           type: PathPrefix
           value: /v1/login
       - path:
           type: PathPrefix
           value: /v1/logout
       filters:
         - type: ExtensionRef
           extensionRef:
             group: gateway.solo.io
             kind: RouteOption
             name: portal-cors
    EOF
      
  3. Update the frontend deployment with the container environment variables that are required for the login feature.

      kubectl apply -n gloo-system -f- <<EOF
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: portal-frontend
      namespace: gloo-system
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: portal-frontend
      namespace: gloo-system
      labels:
        app: portal-frontend
        service: portal-frontend
    spec:
      ports:
        - name: http
          port: 4000
          targetPort: 4000
      selector:
        app: portal-frontend
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: portal-frontend
      namespace: gloo-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: portal-frontend
      template:
        metadata:
          labels:
            app: portal-frontend
        spec:
          serviceAccountName: portal-frontend
          containers:
            - image: gcr.io/solo-public/docs/portal-frontend:latest
              imagePullPolicy: Always
              name: portal-frontend
              args: ["--host", "0.0.0.0"]
              ports:
                - containerPort: 4000
              env:
                - name: VITE_PORTAL_SERVER_URL
                  value: "http://portal.example.com:8080/v1" # The URL that the backend Portal is exposed on via an HTTPRoute.
                - name: VITE_APPLIED_OIDC_AUTH_CODE_CONFIG
                  value: "true"
                - name: VITE_OIDC_AUTH_CODE_CONFIG_CALLBACK_PATH
                  value: "/v1/login"
                - name: VITE_OIDC_AUTH_CODE_CONFIG_LOGOUT_PATH
                  value: "/v1/logout"   
    EOF
      

Step 3: Create an OAuth policy

Use an OAuth2 authorization code policy to protect the portal.

  1. Create a secret with the OAuth credentials for your Keycloak IdP that set up in Step 1.

      kubectl apply -f - <<EOF                  
    apiVersion: v1
    kind: Secret
    metadata:
      name: oauth-keycloak
      namespace: gloo-system
    type: extauth.solo.io/oauth
    stringData:
      client-id: $KEYCLOAK_CLIENT
      client-secret: $KEYCLOAK_SECRET
    EOF
      
  2. Create an AuthConfig with the details from your IdP.

      kubectl apply -f - <<EOF
    apiVersion: enterprise.gloo.solo.io/v1
    kind: AuthConfig
    metadata:
      name: oauth-keycloak
      namespace: gloo-system
    spec:
      configs:
        - oauth2:
            oidcAuthorizationCode:
              appUrl: "http://portal.example.com"
              callbackPath: /v1/login
              logoutPath: /v1/logout
              clientId: $KEYCLOAK_CLIENT
              clientSecretRef:
                name: oauth-keycloak
                namespace: gloo-system
              issuerUrl: "$KEYCLOAK_URL/realms/master"
              session:
                failOnFetchFailure: true
                cookie:
                  allowRefreshing: true
              scopes:
              - openid
              headers:
                idTokenHeader: id_token
    EOF
      

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

    OIDC SettingDescription
    appUrlThe frontend URL for the developer portal. Make sure to update the example if you use a different hostname.
    callbackPathThe callback path on the appUrl. This value matches the /v1/login route in frontend portal’s HTTPRoute.
    logoutPathThe logout path on the appUrl. This value matches the /v1/logout route in frontend portal’s HTTPRoute.
    clientIdThe client ID in your IdP. The example uses the Keycloak variable that you previously set.
    clientSecretRefThe Kubernetes secret that has the client secret of your IdP that you previously created.
    issuerUrlThe URL of the OIDC IdP to use. Gloo Gateway automatically discovers OIDC configuration by querying the .well-known/openid-configuration endpoint on the issuer_url. In this example, Gloo Gateway expects to find OIDC discovery information at "${KEYCLOAK_URL}/realms/master/". If you used a different realm, make sure to update the value accordingly.
    sessionDetails on how to store the user session details. For the frontend app login to work, you must let the session be stored in a local cookie in the browser. Do not configure the session to be stored in Redis.
    scopesScopes to request in addition to the openid scope. This example does not request additional scopes. Make sure that Keycloak returns the custom claims that you configured (name and group: admin) as part of the openid scope. If the claims are attached to a different scope, include that scope in this field.
    idTokenHeaderSet the ID token in the expected id_token header.
  3. Create a RouteOption to apply the AuthConfig, or add the AuthConfig to an existing RouteOption such as the CORS policy that you created earlier to.

      kubectl apply -n gloo-system -f- <<EOF
    apiVersion: gateway.solo.io/v1
    kind: RouteOption
    metadata:
      name: portal-cors
      namespace: gloo-system
    spec:
      options:
        cors:
          allowHeaders:
          - "*"
          allowMethods:
          - GET
          allowOriginRegex:
          - ".*"
        extauth:
          configRef:
            name: oauth-keycloak
            namespace: gloo-system
    EOF
      
  4. Make sure that the RouteOption is attached to the /v1/login and /v1/logout matchers in the HTTPRoute.

      kubectl apply -n gloo-system -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: portal-frontend-route
      namespace: gloo-system
    spec:
      parentRefs:
        - name: http
          namespace: gloo-system
      hostnames:
        - portal.example.com
        - gateway-portal-web-server.gloo-system
      rules:
        - backendRefs:
            - name: portal-frontend
              namespace: gloo-system
              port: 4000
          matches:
          - path:
              type: PathPrefix
              value: /
     - backendRefs:
         - name: portal-frontend
           namespace: gloo-system
           port: 4000
       matches:
       - path:
           type: PathPrefix
           value: /v1/login
       - path:
           type: PathPrefix
           value: /v1/logout
       filters:
         - type: ExtensionRef
           extensionRef:
             group: gateway.solo.io
             kind: RouteOption
             name: portal-cors
    EOF
      

Step 4: Verify the login

You set up the IdP, portal, and the ext auth resources necessary to require users to log in. Now, verify that the login works.

  1. Open the frontend URL.

      open http://portal.example.com
      
  2. From the menu bar, click LOGIN. You are redirected to the login page of your IdP.

    Figure: Welcome page of the developer portal.
    Figure: Welcome page of the developer portal.
    Figure: Welcome page of the developer portal.
    Figure: Welcome page of the developer portal.

  3. From the IdP login page, enter your credentials, such as user2 / password from the Keycloak example. You are redirected back to the portal frontend app.

  4. From the portal frontend app, explore the features that you now have access to because you are logged in. For example, from the menu bar, you now see options for Teams and Apps.

Next steps

Well done! Your users can now log in to the portal frontend app with the credentials managed by your IdP. By logging in, your users can take advantage of self-service features, such as creating their own teams and apps, and to subscribe to API products that they want to have access to. For more information, see Create teams, apps, and subscriptions. To approve, reject, or delete an API subscription, see Manage API subscriptions.

You can also enable self-service for API credentials so that your users can create their own API keys or OAuth clients by using the Portal frontend app. For more information, see Set up credential management for APIs.

To further protect your APIs, you can set up rate limits for the API subscriptions that your Portal users requested. For more information, see Set up rate limiting for APIs.