Azure API Management: Validating Multiple OIDC Issuers for a Single API

Aymen Furter
2 min readJun 8, 2023

--

Azure API Management can give you security-in-depth by already identifying invalid requests containing no or invalid JWT tokens on your requests before they even reach your backend.

You can use the validate-jwt policy to validate any OIDC provider and specify the required claims, audiences, issuers, and signing keys. However, there might be situations where a single API should support multiple issuers. In that case, you can use the choose policy to apply different validation rules based on the issuer claim.

First, we need to identify the issuer. The issuer is encoded in base64 and stored in the JWT. We can use a variable to store the issuer after decoding it.

In the below example we support both AAD as well as an external IDP:

<policies>
<inbound>
<set-variable name="issuer" value="@{
string auth = context.Request.Headers.GetValueOrDefault("Authorization", "");
if (string.IsNullOrEmpty(auth) || !auth.StartsWith("Bearer ")) { return ""; }

string jwt = auth.Substring("Bearer ".Length);
string[] jwtParts = jwt.Split('.');

if (jwtParts.Length != 3) { return ""; }

string payloadBase64 = jwtParts[1];
int paddingLength = payloadBase64.Length % 4;
if (paddingLength > 0)
{
payloadBase64 += new string('=', 4 - paddingLength);
}

string payloadJson = Encoding.UTF8.GetString(Convert.FromBase64String(payloadBase64));
JObject payload = JObject.Parse(payloadJson);

return payload.Value<string>("iss");
}" />
<choose>
<when condition="@(context.Variables.GetValueOrDefault<string>("issuer") == "https://<your-third-party-idp>/")">
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized" require-expiration-time="true" require-scheme="Bearer" require-signed-tokens="true">
<openid-config url="https://<your-third-party-idp>/.well-known/openid-configuration" />
</validate-jwt>
</when>
<otherwise>
<validate-jwt header-name="Authorization" failed-validation-httpcode="403" failed-validation-error-message="Forbidden">
<openid-config url="https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration" />
<issuers>
<issuer>https://sts.windows.net/<tenant-id>/</issuer>
</issuers>
</validate-jwt>
</otherwise>
</choose>
<base />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>

--

--

Aymen Furter

I am a Cloud Solution Architect working for Microsoft. The views expressed on this site are mine alone and do not necessarily reflect the views of my employer.