Microsoft
Let users authenticate with your app by using their Microsoft account.
You can use Gloo Gateway external auth to authenticate users to your apps with other accounts that they have. In this guide, you set up Gloo Gateway to authenticate with users’ Microsoft accounts.
This feature is an Enterprise-only feature that requires a Gloo Gateway Enterprise license.
About
As part of your Microsoft setup, you can use Microsoft Entra ID for cloud-based identity and access management across all your Microsoft resources, such as Microsoft 365 and Azure. You can register users and applications in Entra ID to set up OIDC authentication in Gloo Gateway.
Gloo even supports distributed claims for the identity tokens that are returned. In Azure Active Directory, identity tokens can only support a user’s membership in up to 200 groups. Sometimes, user memberships exceed this limit. In such cases, the authentication fails unless you set up distributed claims. You can give Gloo Gateway the details of your app in Entra ID. Then, behind the scenes, the Gloo external auth service talks to the Microsoft Graph API to retrieve the complete identity token. You can even set up caching, so that the Graph API does not accidentally become throttled if you have many client requests.
You can set up distributed claims for both types of OAuth through an authorization code or an access token. With access token authentication, the distributed claim can be stored in a JWT. The JWT itself can also be in a header other than the expected Authorization: Bearer
header, if you combine the authentication policy with a transformation policy.
Before you begin
Consider increasing the default timeout of the external auth server. When you set up OAuth, the external auth server must communicate with the external OIDC provider’s authorization server. Because of this interaction, the OIDC flow might take longer than the default timeout of 200ms
. In such cases, you might noticed failed requests or unexpected behavior. You can increase the default timeout by setting the requestTimeout
value on the external auth settings. The external auth settings can be configured on the Gloo Gateway Settings object.
Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.
Get the external address of the gateway and save it in an environment variable.
Step 1: Set up Microsoft Entra ID
To use Microsoft Entra ID as an identity provider (IdP), you must set up Entra ID and register your app.
If you have not already, create your user directory. For instructions, see the Microsoft Entra ID docs.
Create and register an app with Microsoft Entra ID. This app is used by the Gloo external auth service for authentication purposes to call the Microsoft Graph API. For instructions, see the Microsoft Entra ID docs. At a minimum, make sure that you set up and note the values of the following fields:
- Overview > Application (client) ID: The client ID that Microsoft Entra generates. Later, you create a Kubernetes secret for the Gloo external auth service with the client ID.
export EXTAUTH_CLIENT_ID=<client-id>
- Overview > Directory (tenant) ID: The tenant ID for when you configure the external auth policy later.
export EXTAUTH_TENANT_ID=<tenant-id>
- Manage > Certificates & secrets: The client secret that Microsoft Entra generates. Later, you create a Kubernetes secret for the Gloo external auth service with the client secret.
export EXTAUTH_SECRET=<secret>
- Overview > Application (client) ID: The client ID that Microsoft Entra generates. Later, you create a Kubernetes secret for the Gloo external auth service with the client ID.
Create and register another app with Microsoft Entra ID. This app represents the backing service that your users want to access, such as an httpbin app. When users access the service, Gloo Gateway handles the OIDC authorization flow and redirects them to Microsoft to authenticate. The identity token is returned upon successful authentication, per the configuration in this app. For instructions, see the Microsoft Entra ID docs. At a minimum, make sure that you set up and note the values of the following fields:
- Overview > Application (client) ID: The client ID that Microsoft Entra generates. Later, you create a Kubernetes secret for the Gloo external auth service with the client ID.
export HTTPBIN_APP_CLIENT_ID=<client-id>
- Overview > Endpoints: The issuer URL for the app, which is similar to the
OpenID Connect metadata document
URL without the/.well-known/openid-configuration
subpath.export HTTPBIN_APP_ISSUER_URL=https://login.microsoftonline.com/<tenant-id>/v2.0
- Manage > Certificates & secrets: The client secret that Microsoft Entra generates. Later, you create a Kubernetes secret for the Gloo external auth service with the client secret.
export HTTPBIN_APP_SECRET=<secret>
- Manage > Authentication: A redirect URI to use as part of the OAuth flow that you set up later. To create a redirect URI for your web app, click Add a platform > Web. Typically, the format of the redirect URI looks similar to
https://<app-url>/callback
. If you do not have a custom domain for your external auth app, you might use the ingress gateway’s address for the<app-url>
. - Manage > App roles: A default role for the app.
- Manage > Token configuration: Add the
groups
claim and any other claim that you want returned in the identity token. - Manage > Expose an API: Add an Application ID URI. Then, use this Application ID URI to add a scope.
export HTTPBIN_APP_SCOPE=api://<app-url>/<scope-name>
- Overview > Application (client) ID: The client ID that Microsoft Entra generates. Later, you create a Kubernetes secret for the Gloo external auth service with the client ID.
Step 2: Prepare routing for your app
Set up the routing for the app that your users want to access. The following example uses the httpbin app. You create an HTTPS listener on a virtual gateway for the httpbin app, which is the same app that you configured an app URL and redirect URI for in Microsoft Entra.
You can skip this step if you already have a custom domain set up for the backing service of the Microsoft app. However, the app URL that you use must be configured for HTTPS traffic.
Create an HTTPS listener on your gateway to expose that app that you want to configure external auth for. This app is the same app that you configured an app URL and redirect URI for in Microsoft Entra.
Create an HTTPRoute for the app that sets up routing rules for the app URL and redirect URI that you configured in Microsoft Entra.
The app URL is the ingress gateway address with the
/ip
matcher that is set up in the following route. If you used a HTTPS domain that you own, update the${INGRESS_GW_ADDRESS}
accordingly, such ashttps://mydomain.com/ip
.export APP_URL=${INGRESS_GW_ADDRESS}/ip
The
/callback
matcher is set up to match the redirect URI that you previously configured in your Microsoft Entra app.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-oauth-microsoft namespace: httpbin spec: hostnames: - "www.httpbin.org" parentRefs: - name: https namespace: gloo-system rules: - matches: - path: type: Exact value: /ip backendRefs: - name: httpbin port: 8000 - matches: - path: type: Exact value: /callback EOF
Verify that the
/ip
route returns a 200 response. If you used a HTTPS domain that you own, update the following command accordingly, such ascurl -vik https://mydomain.com/ip
.curl -vik --resolve "www.httpbin.org:443:${INGRESS_GW_ADDRESS}" https://www.httpbin.org:443/ip
Example output:
... > GET /ip HTTP/2 > Host: www.httpbin.org > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off < HTTP/2 200 HTTP/2 200
Step 3: Create the secrets for the external auth service
Configure the Gloo external auth service to handle the OAuth flow for you. To do so, you create secrets for the external auth service based on the information that you configured in Microsoft Entra.
Store the client secret for the external auth service. This way, the external auth service can talk to the MS Graph API to retrieve distributed claims for users that are members of more than 200 groups. Create the Kubernetes secret in the same cluster that create the auth policy in.
kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: microsoft-extauth namespace: gloo-system type: extauth.solo.io/oauth stringData: client-secret: ${EXTAUTH_SECRET} EOF
Store the client secret of the second Microsoft app that represents the backing service such as httpbin. This way, the external auth service can handle the OIDC flow for requests to the httpbin app in Microsoft Entra. Create the Kubernetes secret in the same cluster that you want to create the auth policy in.
kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: microsoft-httpbin namespace: gloo-system type: extauth.solo.io/oauth stringData: client-secret: ${HTTPBIN_APP_SECRET} EOF
Step 4: Configure the AuthConfig
Create a Rego policy to evaluate requests for user membership in a particular group. Then, create an external auth policy that has two modules. One module sets up Microsoft as an OIDC provider, including distributed claims. The other module sets up OPA to enforce a Rego policy on the identity token that is returned from the OIDC provider.
You can set up distributed claims for both types of OAuth through an authorization code or an access token. With access token authentication, the distributed claim can be stored in a JWT. The JWT itself can also be in a header other than the expected Authorization: Bearer
header, if you combine the authentication policy with a transformation policy.
Create a config map with the Rego policy that you want to enforce. For more information, see the OPA docs. The following Rego policy:
- Sets the input state key to
azure_claims
. Theazure_claims
setting gets thegroups
claim values from the Microsoft OIDC claims in the token, along with any distributed claims. This way, the user can be a member of less than or more than 200 groups. - Iterates through all of the
groups
claim values. - Allows requests if the user is a member of the group with ID
12345-67-89-10111213
. You can update this group ID value accordingly. To find your group IDs in Microsoft Entra, go to Identity > Groups > All groups, search for your group, and copy the Object Id value.
kubectl apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: httpbin-rego namespace: httpbin data: policy.rego: | package test default allow = false allow { # Allow group with ID 12345-67-89-10111213 count({i | input.state["azure_claims"]["groups"][i] == "12345-67-89-10111213"}) > 0 } EOF
- Sets the input state key to
Choose from the following OAuth options.
Want to use multiple OAuth configs in combination? Check out the boolean expression setting in your auth config.
Authorization code
Create an AuthConfig that uses Microsoft for OIDC and enforces the Rego policy. The policy also enables distributed claims and caching for OIDC with Microsoft. You only need distributed claims if the users that authenticate are members in more than 200 groups. If not, you can remove the azure
section from the external auth policy.
kubectl apply -f - <<EOF
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: httpbin-test
namespace: httpbin
spec:
configs:
- oauth2:
oidcAuthorizationCode:
appUrl: $APP_URL
azure:
claimsCachingOptions:
host: redis.gloo-system.svc.cluster.local:6379
clientId: $EXTAUTH_CLIENT_ID
clientSecret:
name: microsoft-extauth
namespace: gloo-system
tenantId: $EXTAUTH_TENANT_ID
callbackPath: /callback
clientId: $HTTPBIN_APP_CLIENT_ID
clientSecretRef:
name: microsoft-httpbin
namespace: gloo-system
issuerUrl: $HTTPBIN_APP_ISSUER_URL
scopes:
- $HTTPBIN_APP_SCOPE
- profile
- email
- openid
session:
redis:
cookieName: oidcsession
options:
host: redis.gloo-system.svc.cluster.local:6379
- name: opa
opaAuth:
modules:
- name: httpbin-rego
namespace: httpbin
query: data.test.allow == true
EOF
Review the following table to understand this configuration. For more information, see the API reference for OAuth2 in the Gloo Edge docs.
Setting | Description |
---|---|
oauth2 | Configure the OAuth 2.0 protocol details to use to authenticate requests. The example uses Microsoft as the external identity provider. Gloo Gateway handles the OIDC flow by validating the contents of an ID token based on the configuration details that you configure in oidcAuthorizationCode . |
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. If your app does not have a custom domain, you can use the address of the ingress gateway and the path that your app is exposed on, such as https://52.xxx.xx.xxx/ip . |
azure | The configuration details for the external auth service to authenticate with the Microsoft Graph API for distributed claims and caching. You use distributed claims for cases where users are members of more than 200 groups. If you do not need distributed claims, you can omit this section.
|
callbackPath | The callback path, relative to the appUrl setting. After a user authenticates, the identity provider redirects the user to this callback URL. Gloo Gateway 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. Note: 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 of the Microsoft Entra ID app for your user-facing service such as httpbin (not the client ID of the app for the external auth service). |
clientSecretRef | The reference to the Kubernetes secret that you previously created for the Microsoft Entra ID app of your user-facing service such as httpbin (not the app for the external auth service). The secret must exist on the same cluster as the ExtAuthServer resource that this policy refers to. |
issuerUrl | The URL of the OpenID Connect identity provider. 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 the address in Microsoft Entra that you previously retrieved, https://login.microsoftonline.com/<tenant-id>/v2.0 . |
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. For Azure, you must also include the api scope, which is the Application ID URI that you previously configured in Microsoft Entra. This example also requests the email and profile scopes. For more information, see the OpenID docs. |
session | Details on how to store the user session details. In this example, the cookie is stored in Redis. |
opaAuth | The configuration details for the OPA policy that you want to enforce.
|
Access token
Create an external auth policy that uses Microsoft for OIDC and enforces the Rego policy. Review the following key features of the policy.
- The policy retrieves the access token from a JWT from your MS Entra issuer.
- The policy also enables distributed claims and caching for OIDC with Microsoft. You only need distributed claims if the users that authenticate are members in more than 200 groups. If not, you can remove the
azure
section from the external auth policy.
Authorization: Bearer <token>
header format. If you use a different header, apply a transformation policy.
kubectl apply -f - <<EOF
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: httpbin-test
namespace: httpbin
spec:
configs:
- oauth2:
accessTokenValidation:
jwt:
remoteJwks:
url: <jwks_url>
issuer: <issuer_url>
claimsToHeaders:
- claim: groups
header: x-groups
azure:
claimsCachingOptions:
host: redis.gloo-system.svc.cluster.local:6379
clientId: $EXTAUTH_CLIENT_ID
clientSecret:
name: microsoft-extauth
namespace: gloo-system
tenantId: $EXTAUTH_TENANT_ID
- name: opa
opaAuth:
modules:
- name: httpbin-rego
namespace: httpbin
query: data.test.allow == true
EOF
Review the following table to understand this configuration. For more information, see the API reference for OAuth2 in the Gloo Edge docs.
Setting | Description |
---|---|
oauth2 | Configure the OAuth 2.0 protocol details to use to authenticate requests. The example uses Microsoft as the external identity provider. Gloo Gateway handles the OIDC flow by validating the contents of an access token based on the configuration details that you configure in accessTokenValidation . |
jwt | Configure the details for how to verify the JWT, such as the issuer and JSON Key Web set (JWKS) locations. The example uses a remote JWKS, but you can inline a local JWKS instead. |
remoteJwks | The JWKS server to get the public keys from. You get this URL from your MS Entra instance. Note that this URL must be reachable from your cluster. |
issuer | The principal that issued the JWT, usually a URL from your MS Entra instance. If specified, the iss field in JWT token of the incoming request must match this field, or else the request is denied. If omitted, the iss field in the JWT token is not checked. |
claimsToHeaders | Optionally, you can copy claims from the JWT to individual headers before forwarding the request. For example, you might want an x-groups header to contain the content from the groups claim in the JWT. |
azure | The configuration details for the external auth service to authenticate with the Microsoft Graph API for distributed claims and caching. You use distributed claims for cases where users are members of more than 200 groups. If you do not need distributed claims, you can omit this section.
|
opaAuth | The configuration details for the OPA policy that you want to enforce.
|
Step 5: Attach the AuthConfig to your route
To attach the AuthConfig to your route, you can use a RouteOption. For more options, see Policy attachment.
Create a RouteOption that refers to the AuthConfig that you created.
kubectl apply -f- <<EOF apiVersion: gateway.solo.io/v1 kind: RouteOption metadata: name: httpbin-oauth namespace: httpbin spec: options: extauth: configRef: name: httpbin-test namespace: httpbin EOF
Update your HTTPRoute resource to attach the RouteOption to the
/ip
route by using anExtensionRef
filter.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-oauth-microsoft namespace: httpbin spec: hostnames: - "www.httpbin.org" parentRefs: - name: https namespace: gloo-system rules: - matches: - path: type: Exact value: /ip backendRefs: - name: httpbin port: 8000 filters: - type: ExtensionRef extensionRef: group: gateway.solo.io kind: RouteOption name: httpbin-oauth - matches: - path: type: Exact value: /callback EOF
Step 6: Verify the OAuth policy
The following steps show how you might authenticate with your Microsoft user account when using OAuth2 authorization code authentication.
Send a curl request to your application. Verify that you get back a 302 Found code, because the request is temporarily moved to the Microsoft OIDC authentication flow.
curl -vik $APP_URL
Example output:
HTTP/2 302 < location: https://login.microsoftonline.com/...
In your web browser, open the path to your application, such as the ingress gateway IP address and the path that you configured in the route table. You are redirected to the authentication page from the Microsoft identity provider.
open $APP_URL
Enter your Microsoft user credentials.
Figure: Microsoft login page Figure: Microsoft login page Example output for authorized users: Gloo Gateway redirects you to the app URL, such as
52.xxx.xx.x/ip
. In this example, the httpbin app returns the origin IP address,10.xx.xx.x
.Figure: Example response of origin IP address Figure: Example response of origin IP address Example output for unauthorized users: If you log in as a user that is not authorized to the group, you see a
Rejected
message similar to the following figure.Figure: Example response of rejected unauthorized user Figure: Example response of rejected unauthorized user
Cleanup
You can optionally remove the resources that you set up as part of this guide.
kubectl delete Secret microsoft-extauth -n gloo-system
kubectl delete Secret microsoft-httpbin -n gloo-system
kubectl delete ConfigMap httpbin-rego -n httpbin
kubectl delete AuthConfig httpbin-test -n httpbin
kubectl delete RouteOption httpbin-oauth -n httpbin
kubectl delete HTTPRoute httpbin-oauth-microsoft -n httpbin