Skip to main content

Version: 3.11.0

Set Up SSO with Microsoft Entra ID (Azure AD)

OpenID Connect (OIDC) is a simple identity layer on top of the OAuth 2.0 protocol. It allows clients to verify the identity of end users based on the authentication performed by the identity provider, as well as to obtain basic profile information about end users in an interoperable and REST-like manner. With APISIX and Microsoft Entra ID (formerly Azure AD), you can implement OIDC-based authentication processes to protect your APIs and enable single sign-on (SSO).

Microsoft Entra ID is Microsoft's cloud-based identity and access management service. It allows organizations to securely manage and authenticate users and devices, ensuring that the right individuals have the appropriate access to company resources. Microsoft Entra ID offers features such as single sign-on (SSO), multi-factor authentication (MFA), and integration with various third-party applications.

The guide will show you how to integrate APISIX with Microsoft Entra ID using authorization code flow and client credentials flow.

Prerequisite(s)

  • Install Docker.
  • Install cURL to send requests to the services for validation.
  • Follow the Getting Started tutorial to start a new APISIX instance in Docker.
  • Create an Azure account that has an active subscription.

Register an application in Azure

Log in to the Azure portal, go to the App registrations service and register a new application.

azure-ad-create-an-app

Once the app is registered, click on the Authentication tab and click on Add a platform. Choose Web application type and add a new redirect URI http://localhost:9080/anything/callback to the Redirect URIs list under the Web page. This is the address that the application redirects users to upon a successful authentication with Microsoft Entra ID. Click on Configure to save changes.

azure-ad-app-add-redirect-uri

To configure Microsoft Entra ID to use v2.0 tokens, edit your application Manifest, and set accessTokenAcceptedVersion to 2.

azure-ad-update-manifest

In Certificates & Secrets tab, create a client secret and save the value to a secure location so that you can use it later for APISIX OIDC plugin configuration. You can only view the secret once.

azure-ad-create-secret

Navigate back to the Overview tab and find Directory (tenant) ID and Application (client) ID. Save them to environment variables along with the client secret:

# replace with your values
export TENANT_ID=dcbd8da3-e0b3-486c-9212-08a199dc3451
export CLIENT_ID=e0951842-d546-4c63-9e9e-d33a527673de
export CLIENT_SECRET=wSY8Q~x4z2Tn6Rq5lA4NTtZ6GLBMGvZF_R2LEcPx

Configure APISIX

In this section, you will create a route with OIDC that forwards client requests to httpbin.org, a public HTTP request and response service.

The route /anything/{anything} of httpbin.org returns anything passed in request data in JSON type, such as methods, arguments, and headers.

Enable OIDC Plugin

Create the route and enable the plugin openid-connect:

curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "auth-with-oidc",
"uri":"/anything/*",
"plugins": {
"openid-connect": {
"client_id": "'"$CLIENT_ID"'",
"client_secret": "'"$CLIENT_SECRET"'",
"discovery": "https://login.microsoftonline.com/'"$TENANT_ID"'/v2.0/.well-known/openid-configuration",
"scope": "openid",
"redirect_uri": "http://localhost:9080/anything/callback"
}
},
"upstream":{
"type":"roundrobin",
"nodes":{
"httpbin.org:80":1
}
}
}'

client_id: Microsoft Entra ID client ID.

client_secret: Microsoft Entra ID client secret.

discovery: URI to OIDC discovery document of the identity provider.

redirect_uri: URI to redirect to after authentication with the identity provider.

Authenticate with User Credentials

Navigate to http://localhost:9080/anything/test in a browser. You should be redirected to the Microsoft Entra ID sign-in page:

Microsoft Entra ID Authentication Page

info

You can customize Microsoft Entra ID sign-in page for your own branding. See how to configure your company branding on the sign-in page.

Sign in with your Azure credentials. You should see a response similar to the following in the browser:

{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-us",
"Cookie": "session=...",
"Host": "localhost",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15",
"X-Access-Token": "eyJ...",
"X-Amzn-Trace-Id": "Root=1-65698cfb-262bc17d50bca6de3e855301",
"X-Forwarded-Host": "localhost",
"X-Id-Token": "eyJ...",
"X-Userinfo": "eyJ..."
},
"json": null,
"method": "GET",
"origin": "172.24.0.1, 108.**.**.**",
"url": "http://localhost/anything/test"
}

Authenticate with Client Credentials

The client credentials flow involves an machine-to-machine (M2M) application exchanging credentials with services where there is no user involved.

In this section, you will update the existing route with additional OIDC configurations and authenticate to Microsoft Entra ID with an access token.

Update OIDC Plugin

Update the OIDC plugin on the route to allow only bearer token requests and allow to use the JWKS endpoint of the identity server to verify the token:

curl -i "http://127.0.0.1:9180/apisix/admin/routes/auth-with-oidc" -X PATCH -d '
{
"plugins": {
"openid-connect": {
"bearer_only": true,
"use_jwks": true
}
}
}'

Test Access Token

Obtain an access token for the registered test application in Azure:

curl -i "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token" -X POST \
-d 'client_id='$CLIENT_ID'' \
-d 'client_secret='$CLIENT_SECRET'' \
-d 'scope='$CLIENT_ID'/.default' \
-d 'grant_type=client_credentials'

The expected response is similar to the following:

{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ii1LSTNROW5OUjdiUm9meG1lWm9YcWJIWkdldyJ9.eyJhdWQiOiJlMDk1MTg0Mi1kNTQ2LTRjNjMtOWU5ZS1kMzNhNTI3NjczZGUiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vZGNiZDhkYTMtZTBiMy00ODZjLTkyMTItMDhhMTk5ZGMzNDUxL3YyLjAiLCJpYXQiOjE2OTQ2MDczMzAsIm5iZiI6MTY5NDYwNzMzMCwiZXhwIjoxNjk0NjExMjMwLCJhaW8iOiJBU1FBMi84VUFBQUFHZXcvTjhPQm1OSEtaK1cydVNnR0NNckhwRlNERmVuNUNBcTVONG1QQ2ZzPSIsImF6cCI6ImUwOTUxODQyLWQ1NDYtNGM2My05ZTllLWQzM2E1Mjc2NzNkZSIsImF6cGFjciI6IjEiLCJvaWQiOiIxODA5NTNiZi1lZDZlLTRjNjUtYmRiZS01Y2JlNmRhMTI4OTYiLCJyaCI6IjAuQVRvQW80MjkzTFBnYkVpU0VnaWhtZHcwVVVJWWxlQkcxV05NbnA3VE9sSjJjOTdoQUFBLiIsInN1YiI6IjE4MDk1M2JmLWVkNmUtNGM2NS1iZGJlLTVjYmU2ZGExMjg5NiIsInRpZCI6ImRjYmQ4ZGEzLWUwYjMtNDg2Yy05MjEyLTA4YTE5OWRjMzQ1MSIsInV0aSI6IlM5anBfWS1qUjBhcm9lS3NVdnNqQUEiLCJ2ZXIiOiIyLjAifQ.bAt8rh56MK7igDZws0mtSqXDhHvwIyKoxOW7uqSD5aWBaXPxINpNTqIW04n4_p14uLhBlxSufV8WHmS5V1Pdv-QENu9VMUs00blOH38TX0S3WfyCkYuecvWnHc4kYi4TFxTVk1nTvhU7LgOYIHLDb04rRxP-D0tFJ7qo2gI2nSvDChEPCID8WkugPbXJyo1gc49UAuv75d2PhFkidIigDq_DGQQoa88ZLW1iDcQYVgTitEg9zhqSlYksOq1xGClB16sSubnKF6dwqXOfUamAMeu41YLDdgOAb3bS3J54OOe5uUliemHxWo4Z-rfBOI8uOKUioVLv2RImaHylhutaeA"
}

Save the access token to an environment variable:

# replace with your access toke
export ACCESS_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ikc2elVuYzgtM0JrVlgtZmdnMTdKNSJ9.eyJpc3MiOiJodHRwczovL2Rldi00bGc0aWZzcTRqdnBuN3MyLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJlQUM4VVRWUEZpcnVmT2g0YTFEWnRjN0YyMHo3eUd1dkBjbGllbnRzIiwiYXVkIjoiaHR0cHM6Ly9jbGllbnRjcmVkZW50aWFscy5jb20iLCJpYXQiOjE2OTMwNDAwMjcsImV4cCI6MTY5MzEyNjQyNywiYXpwIjoiZUFDOFVUVlBGaXJ1Zk9oNGExRFp0YzdGMjB6N3lHdXYiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.aePOiFlW0q0mlrQwKdtP1MGfY2nX7TSnTrEjoJI03aG7lBCHhPX_WwszhYvtM5c_cyQtcI6R4ibPskpTssdEXGCe2wbOhstPWeIb9rCFf_kA_g0p1wDM8j8egRfl7PLmFffaEmU0eNrgmjTgYQ0Erk63XDykPFOFWiQKPfDQ2hf4jz_3J_VKNqwy7yQuxisnD5TysybGmrONoiBjYLGIymk1ii-qKEoNt5_DRv10aSBwyRtxDZbiwhAKcWNO7zLaJVmZZLg1aTiRYxgIOU-_AP4iAR6Y4vK_GxyHqf7G6j6yH8wqCj8Nm2bLEg8Gqb9Fd-xbpbQCiC3X14ja5NTYtw"

Send a request to the route with the valid access token authorization header:

curl -i "http://127.0.0.1:9080/anything/test" -H "Authorization: Bearer $ACCESS_TOKEN"

An HTTP/1.1 200 OK response verifies that the client application is able to make authorized calls to the API.

Next Steps

APISIX supports more OIDC identity providers, such as Okta, Keycloak, Authgear and Auth0.

In addition, APISIX also supports built-in authentication approaches such as key authentication, basic authentication, and JWT.


API7.ai Logo

API Management for Modern Architectures with Edge, API Gateway, Kubernetes, and Service Mesh.

Product

API7 Cloud

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2024. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the

Apache Software Foundation