Integrate Azure AD B2C into Azure APIM Developer Portal and Secure APIs with validating JWT Token
Tags: azure, api, azureadb2c, activedirectory
Published: 2024-03-23 20:52:17

## Prerequisites

- Azure AD B2C Tenant.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhij5nb3gpxj1u6s8k5c.png)

- An application that's registered in your tenant.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9yzxkku0vacww9ib80vr.png)

- User flows that are created in your tenant.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ibt8x8bfbv93h21ux5g6.png)

- A published API in Azure API Management.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhhdfobx7dsyz16byj43.png)

- (Optional) A Postman platform to test secured access.

## Let’s Begin 
Let’s assume that we have one Azure AD B2C Tenant and Azure APIM Default Application is ready with us.

## Azure AD B2C
**Azure AD B2C Tenant > App Registrations -**

1. Here, create new app registration using option - ‘+ New registration’

2. Copy its Application/Client Id, which we will require later.

3. In that registered app, go to ‘Certificates & secrets’ option. Choose ‘+ New client secret’ and copy the secret value as it will get shown very first time only.

4. Go to ‘Authentication’ option now within same registered app, choose ‘+ Add a platform’ > Web Redirect URIs > Hold On here, we will paste Azure APIM’s oauth configured URI here (its explanation and value is available in this document in later points). Search for [AzureAPIMAuth] within this document and paste that URI here. This URI comers from Azure APIM developer portal’s ‘OAuth 2.0 + OpenID Connect’ sections’ newly created ‘OAuth 2.0 Service’ > ‘Authorization code grant flow’ redirect URI.
 

5. Go to ‘Authentication’ option now within same registered app, choose ‘+ Add a platform’ > Single-page application Redirect URIs > here, paste Azure APIM developer portal with ‘signin’ like [link/signin]. For example - https://{azure apim app}.developer.azure-api.net/signin and one more https://jwt.ms

6. Go to ‘Expose an API’ option now within same registered app, choose ‘+ Add a scope’ > give permission name and description like app.readwrite.

7. Go to ‘Add Permissions’ option now within same registered app, choose ‘+ Add a permission’ > select app.readwrite scope we created earlier > ‘Grant admin consent for {name}’ > verify all listed permissions status is granted.

8. Note down the ‘Directory (tenant) Id’ from ‘Overview’ option, will require it later.

9. Also, copy and paste all endpoints from ‘Overview’ option, we will require few of them later. (Authorize/Token/OpenId config)

**Azure AD B2C Tenant > User flows –**
Here we will create 2 user flows: 

- Sign Up and Sign In (Recommended).

1. Properties - 
 - Type of method – Email.
 - MFA enforcement – as you wish, ‘Always On’ is recommended.
 - Self-service password reset – yes.
 - Forced password reset - yes.
2. Identity providers – Email
3. User attributes –
 - Display name
 - Email address
4. Application claims –
 - Email addresses
 - Identity provider
 - Identity provider access token
 - Surname
 - User’s object id
- Sign In using resource owner password credentials.

## Azure APIM App
**Azure APIM App > APIs –**
1. Go to ‘All APIs’ > Inbound processing > ‘Policies </>’ >
`<policies>
    <inbound>
        <cors allow-credentials="true">
            <allowed-origins>
                <origin>https://{Azure AD B2C}.b2clogin.com</origin>
                <origin>https://{Azure AD B2C}.onmicrosoft.com</origin>
                <origin>https://login.microsoftonline.com</origin>
                <origin>https://{Azure APIM App}.azure-api.net</origin>
            </allowed-origins>
            <allowed-methods preflight-result-max-age="300">
                <method>*</method>
            </allowed-methods>
            <allowed-headers>
                <header>*</header>
            </allowed-headers>
            <expose-headers>
                <header>*</header>
            </expose-headers>
        </cors>
    </inbound>
    <backend>
        <forward-request />
    </backend>
    <outbound />
    <on-error />
</policies>`

2. After all APIs > there will be APIs which you have added or by default there is one API called ‘Echo API’ > Inbound processing > ‘Policies </>’ >
`<policies>
    <inbound>
        <base />
        <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Authorization failed">
            <openid-config url="https://{Azure AD B2C}.b2clogin.com/{Azure AD B2C}.onmicrosoft.com/{User flow name for recommended sign up and sign in}/v2.0/.well-known/openid-configuration" />
            <audiences>
                <audience>{Azure AD B2C Registered App’s Application/client id}</audience>
            <issuers>
                <issuer>https://{Azure AD B2C}.b2clogin.com/{Azure AD B2C tenant Id}/v2.0/</issuer>
            </issuers>
            <required-claims>
                <claim name="aud">
                    <value>>{Azure AD B2C Registered App’s Application/client id}</value>
                </claim>
            </required-claims>
        </validate-jwt>
        <set-header name="tenant" exists-action="append">
            <value>@{
                        var jwt = context.Request.Headers.GetValueOrDefault("Authorization").AsJwt();
            return jwt?.Claims.GetValueOrDefault("tenant") ?? "unknown"; 
            }</value>
        </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>`
3. After all APIs > there will be APIs which you have added or by default there is one API called ‘Echo API’ > there will be below tabs: Design/Settings/Test/Revisions/Change Log > Choose ‘Settings’ tab> go to ‘Security’ section > User Authorization > there will be 3 options: None (by default selected option)/OAuth2.0/OpenId Connect > choose ‘OAuth2.0’ option > it will ask to select ‘OAuth2.0 server’ > choose the name which you have configured in Azure APIM App (this configuration is described later below, please refer the same here).

**Azure APIM App > Developer Portal > Identities –**
1. By default, there will be basic ‘Username and password’ identity will be there in this section.
2. Choose option ‘+ Add’ and select ‘Azure Active Directory B2C’ option:
 - Client id – Azure AD B2C’s registered app’s client id
 - Client secret – the one which we have copied and saved as it get shown only once.
 - Sign in tenant – https://{Azure AD B2C}.onmicrosoft.com
 - Authority - https://{Azure AD B2C}.b2clogin.com
 - Client library – MSAL
 - Signup policy - /{User flow name for recommended sign up and sign in}
 - Sign in policy - /{User flow name for recommended sign up and sign in}
 - After configuring these settings you will get below url- https://{azure apim app}.developer.azure-api.net/signin 
Which we will use in above points. Reference - Azure AD B2C  > ‘Azure AD B2C Tenant > App Registrations -’ > point number 5.
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfv828g41jx3xv9igsw5.png)

**Azure APIM App > OAuth2.0 + OpenId Connect –**
1. Choose OAuth2.0 > ‘+Add’ > 
 - Display name – provide the name, the one which we will choose in above points. Reference – Azure APIM App > ‘Azure APIM App > APIs –’ > Point no. 3.
 - Description – enter description.
 - Client registration page url - https://{Azure APIM App}.azure-api.net
 - Authorization grant type – Authorization code
 - Authorization endpoint url - https://{Azure AD B2C}.b2clogin.com/{Azure AD B2C}.onmicrosoft.com/{User flow name for recommended sign up and sign in}/oauth2/v2.0/authorize
 - Authorization request method – select both – get and post
 - Token endpoint url - https://{Azure AD B2C}.b2clogin.com/{Azure AD B2C}.onmicrosoft.com/{User flow name for recommended sign up and sign in}/oauth2/v2.0/token
 - Authorization request method -In the body
 - Access token sending method – authorization header
 - Default scope – the one which we created in above points. Reference - Azure AD B2C  > ‘Azure AD B2C Tenant > App Registrations -’ > point number 6. Example – ‘https://{Azure AD B2C}.onmicrosoft.com/{ Azure AD B2C’s registered app’s client id }/app.readwrite’
 - Client credential
   1. Client id – Azure AD B2C’s registered app’s client id
   2. Client secret – the one which we have copied and saved as it get shown only once.
 - Redirect URI-
   1. Authorization code grant flow- this will be auto generated url which you need to use in one of the above points. Reference - Azure AD B2C  > ‘Azure AD B2C Tenant > App Registrations -’ > point number 4. [AzureAPIMAuth]. Example - https://{Azure APIM App}.azure-api.net/signin-oauth/code/callback/{configured oauth name}
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyx4rymktmxn5609hoqu.png)

## Its Done!
**Let’s test it –**
1. Before starting, make sure you have configured Azure AD B2C login UI on Azure APIM Developer portal. If not, go to Azure APIM App’s > developer portal > Go to Sign in page > add button > select Azure AD B2C Login button. Also please take care of below additional things-
 - Add products in Azure APIM App
 - When you logged in successfully in Azure APIM Developer Portal using Azure AD B2C > Go to products and subscribe to any products.
    1. When you will subscribe to any product > In Azure APIM Product Subscriptions section > you can activate that requested subscription to respective User.
    2. Subscription key is mandatory while executing any API for respective product.
 - Also, when you will sign up using Azure AD B2C option within Azure APIM Developer portal > User will first get created at Azure AD B2C. Then it will ask to ‘Complete Sign Up’; so that same user will get created in Azure APIM App’s Users.
 - These Azure APIM App’s users’ > you can add them to any specific groups like developers/guests/admin – these are default groups. You can create your own groups also. UI can be customized as per the group validation also.
2. Publish the Azure APIM App.
3. Now we are good for testing!
 - We can directly test the login and API Authorization from published Azure APIM Developer Portal App-

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3ce5m1mln9687gyjocc.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vlh227cz52bfusyp2ln5.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qb0vzx9vh7fvicw8oeh4.png)

 - We can also test the only API(Anyone from Azure APIM App > APIs) from Postman-
   1. Here, for testing purpose we will use second user flow which we have created - https://{Azure AD B2C}.b2clogin.com/{Azure AD B2C}.onmicrosoft.com/{second user flow - Sign In using resource owner password credentials.}/oauth2/v2.0/token
   2. Type - POST
   3. Body -
      - x-www-form-urlencoded
      - grant_type - password
      - client_id – Azure AD B2C’s registered App’s client id
      - scope - Azure AD B2C’s registered App’s scope
      - username – successfully signed up user email
      - password - successfully signed up user password
      - resource_type – token

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w2nn6yk41clkxcvzlfad.png)