Set up a secure login
Integrate the frontend app with your OIDC provider to set up secure OAuth authentication.
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
- Complete the tutorial to set up Gloo Portal.
- 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.
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
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
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.
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
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 Setting Description appUrl
The frontend URL for the developer portal. Make sure to update the example if you use a different hostname. callbackPath
The callback path on the appUrl
. This value matches the/v1/login
route in frontend portal’s HTTPRoute.logoutPath
The logout path on the appUrl
. This value matches the/v1/logout
route in frontend portal’s HTTPRoute.clientId
The client ID in your IdP. The example uses the Keycloak variable that you previously set. clientSecretRef
The Kubernetes secret that has the client secret of your IdP that you previously created. issuerUrl
The 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.session
Details 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. scopes
Scopes 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
andgroup: admin
) as part of theopenid
scope. If the claims are attached to a different scope, include that scope in this field.idTokenHeader
Set the ID token in the expected id_token
header.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
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.
Open the frontend URL.
open http://portal.example.com
For local testing, add the gateway proxy IP address to your/etc/hosts
file for the frontend host, such as18.xxx.xxx.xx portal.example.com
.From the menu bar, click LOGIN. You are redirected to the login page of your IdP.
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.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.