Secure your RESTful services

Note

In Azure Active Directory B2C, custom policies are designed primarily to address complex scenarios. For most scenarios, we recommend that you use built-in user flows.

When integrating a REST API within an Azure AD B2C user journey, you must protect your REST API endpoint with authentication. This ensures that only services that have proper credentials, such as Azure AD B2C, can make calls to your REST API endpoint.

Learn how to integrate a REST API within your Azure AD B2C user journey in the validate user input and Add REST API claims exchanges to custom policies articles.

This article will explore how to secure your REST API with either HTTP basic, client certificate or OAuth2 authentication.

Prerequisites

Complete the steps in one of the following 'How to' guides:

HTTP basic authentication

HTTP basic authentication is defined in RFC 2617. Basic authentication works as follows: Azure AD B2C sends an HTTP request with the client credentials in the Authorization header. The credentials are formatted as the base64-encoded string "name:password".

Add REST API username and password policy keys

To configure a REST API technical profile with HTTP basic authentication, create the following cryptographic keys to store the username and password:

  1. Sign in to the Azure portal.
  2. Make sure you're using the directory that contains your Azure AD B2C tenant. Select the Directory + subscription filter in the top menu and choose your Azure AD B2C directory.
  3. Choose All services in the top-left corner of the Azure portal, and then search for and select Azure AD B2C.
  4. On the Overview page, select Identity Experience Framework.
  5. Select Policy Keys, and then select Add.
  6. For Options, select Manual.
  7. For Name, type RestApiUsername. The prefix B2C_1A_ might be added automatically.
  8. In the Secret box, enter the REST API username.
  9. For Key usage, select Encryption.
  10. Select Create.
  11. Select Policy Keys again.
  12. Select Add.
  13. For Options, select Manual.
  14. For Name, type RestApiPassword. The prefix B2C_1A_ might be added automatically.
  15. In the Secret box, enter the REST API password.
  16. For Key usage, select Encryption.
  17. Select Create.

Configure your REST API technical profile to use HTTP basic authentication

After creating the necessary keys, configure your REST API technical profile metadata to reference the credentials.

  1. In your working directory, open the extension policy file (TrustFrameworkExtensions.xml).
  2. Search for the REST API technical profile. For example REST-ValidateProfile, or REST-GetProfile.
  3. Locate the <Metadata> element.
  4. Change the AuthenticationType to Basic.
  5. Change the AllowInsecureAuthInProduction to false.
  6. Immediately after the closing </Metadata> element, add the following XML snippet:
    <CryptographicKeys>
        <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_RestApiUsername" />
        <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_RestApiPassword" />
    </CryptographicKeys>
    

The following is an example of a RESTful technical profile configured with HTTP basic authentication:

<ClaimsProvider>
  <DisplayName>REST APIs</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="REST-GetProfile">
      <DisplayName>Get user extended profile Azure Function web hook</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://your-account.azurewebsites.net/api/GetProfile?code=your-code</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">Basic</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_RestApiUsername" />
        <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_RestApiPassword" />
      </CryptographicKeys>
      ...
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

HTTPS client certificate authentication

Client certificate authentication is a mutual certificate-based authentication, where the client, Azure AD B2C, provides its client certificate to the server to prove its identity. This happens as a part of the SSL handshake. Only services that have proper certificates, such as Azure AD B2C, can access your REST API service. The client certificate is an X.509 digital certificate. In production environments, it must be signed by a certificate authority.

Prepare a self-signed certificate (optional)

For non-production environments, if you don't already have a certificate, you can use a self-signed certificate. On Windows, you can use PowerShell's New-SelfSignedCertificate cmdlet to generate a certificate.

  1. Execute this PowerShell command to generate a self-signed certificate. Modify the -Subject argument as appropriate for your application and Azure AD B2C tenant name. You can also adjust the -NotAfter date to specify a different expiration for the certificate.
    New-SelfSignedCertificate `
        -KeyExportPolicy Exportable `
        -Subject "CN=yourappname.yourtenant.onmicrosoft.com" `
        -KeyAlgorithm RSA `
        -KeyLength 2048 `
        -KeyUsage DigitalSignature `
        -NotAfter (Get-Date).AddMonths(12) `
        -CertStoreLocation "Cert:\CurrentUser\My"
    
  2. Open Manage user certificates > Current User > Personal > Certificates > yourappname.yourtenant.onmicrosoft.com.
  3. Select the certificate > Action > All Tasks > Export.
  4. Select Yes > Next > Yes, export the private key > Next.
  5. Accept the defaults for Export File Format.
  6. Provide a password for the certificate.

Add a client certificate policy key

  1. Sign in to the Azure portal.
  2. Make sure you're using the directory that contains your Azure AD B2C tenant. Select the Directory + subscription filter in the top menu and choose your Azure AD B2C directory.
  3. Choose All services in the top-left corner of the Azure portal, and then search for and select Azure AD B2C.
  4. On the Overview page, select Identity Experience Framework.
  5. Select Policy Keys, and then select Add.
  6. In the Options box, select Upload.
  7. In the Name box, type RestApiClientCertificate. The prefix B2C_1A_ is added automatically.
  8. In the File upload box, select your certificate's .pfx file with a private key.
  9. In the Password box, type the certificate's password.
  10. Select Create.

Configure your REST API technical profile to use client certificate authentication

After creating the necessary key, configure your REST API technical profile metadata to reference the client certificate.

  1. In your working directory, open the extension policy file (TrustFrameworkExtensions.xml).
  2. Search for the REST API technical profile. For example REST-ValidateProfile, or REST-GetProfile.
  3. Locate the <Metadata> element.
  4. Change the AuthenticationType to ClientCertificate.
  5. Change the AllowInsecureAuthInProduction to false.
  6. Immediately after the closing </Metadata> element, add the following XML snippet:
    <CryptographicKeys>
       <Key Id="ClientCertificate" StorageReferenceId="B2C_1A_RestApiClientCertificate" />
    </CryptographicKeys>
    

The following is an example of a RESTful technical profile configured with an HTTP client certificate:

<ClaimsProvider>
  <DisplayName>REST APIs</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="REST-GetProfile">
      <DisplayName>Get user extended profile Azure Function web hook</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://your-account.azurewebsites.net/api/GetProfile?code=your-code</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">ClientCertificate</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="ClientCertificate" StorageReferenceId="B2C_1A_RestApiClientCertificate" />
      </CryptographicKeys>
      ...
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

OAuth2 bearer authentication

Note

This feature is in public preview.

Bearer token authentication is defined in OAuth2.0 Authorization Framework: Bearer Token Usage (RFC 6750). In bearer token authentication, Azure AD B2C sends an HTTP request with a token in the authorization header.

Authorization: Bearer <token>

A bearer token is an opaque string. It can be a JWT access token or any string that the REST API expects Azure AD B2C to send in the authorization header. Azure AD B2C supports the following types:

  • Bearer token. To be able to send the bearer token in the Restful technical profile, your policy needs to first acquire the bearer token and then use it in the RESTful technical profile.
  • Static bearer token. Use this approach when your REST API issues a long-term access token. To use a static bearer token, create a policy key and make a reference from the RESTful technical profile to your policy key.

Using OAuth2 Bearer

The following steps demonstrate how to use client credentials to obtain a bearer token and pass it into the Authorization header of the REST API calls.

Define a claim to store the bearer token

A claim provides temporary storage of data during an Azure AD B2C policy execution. The claims schema is the place where you declare your claims. The access token must be stored in a claim to be used later.

  1. Open the extensions file of your policy. For example, SocialAndLocalAccounts/TrustFrameworkExtensions.xml.
  2. Search for the BuildingBlocks element. If the element doesn't exist, add it.
  3. Locate the ClaimsSchema element. If the element doesn't exist, add it.
  4. Add the following claims to the ClaimsSchema element.
<ClaimType Id="bearerToken">
  <DisplayName>Bearer token</DisplayName>
  <DataType>string</DataType>
</ClaimType>
<ClaimType Id="grant_type">
  <DisplayName>Grant type</DisplayName>
  <DataType>string</DataType>
</ClaimType>
<ClaimType Id="scope">
  <DisplayName>scope</DisplayName>
  <DataType>string</DataType>
</ClaimType>

Acquiring an access token

You can obtain an access token in one of several ways: by obtaining it from a federated identity provider, by calling a REST API that returns an access token, by using an ROPC flow, or by using the client credentials flow.

The following example uses a REST API technical profile to make a request to the Azure AD token endpoint using the client credentials passed as HTTP basic authentication. To configure this in Azure AD, see Microsoft identity platform and the OAuth 2.0 client credentials flow. You may need to modify this to interface with your Identity Provider.

For the ServiceUrl, replace your-tenant-name with the name of your Azure AD tenant. See the RESTful technical profile reference for all options available.

<TechnicalProfile Id="SecureREST-AccessToken">
  <DisplayName></DisplayName>
  <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  <Metadata>
    <Item Key="ServiceUrl">https://login.microsoftonline.com/your-tenant-name.onmicrosoft.com/oauth2/v2.0/token</Item>
    <Item Key="AuthenticationType">Basic</Item>
     <Item Key="SendClaimsIn">Form</Item>
  </Metadata>
  <CryptographicKeys>
    <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_SecureRESTClientId" />
    <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_SecureRESTClientSecret" />
  </CryptographicKeys>
  <InputClaims>
    <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="client_credentials" />
    <InputClaim ClaimTypeReferenceId="scope" DefaultValue="https://secureb2cfunction.azurewebsites.net/.default" />
  </InputClaims>
  <OutputClaims>
    <OutputClaim ClaimTypeReferenceId="bearerToken" PartnerClaimType="access_token" />
  </OutputClaims>
  <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>

Change the REST technical profile to use bearer token authentication

To support bearer token authentication in your custom policy, modify the REST API technical profile with the following:

  1. In your working directory, open the TrustFrameworkExtensions.xml extension policy file.

  2. Search for the <TechnicalProfile> node that includes Id="REST-API-SignUp".

  3. Locate the <Metadata> element.

  4. Change the AuthenticationType to Bearer, as follows:

    <Item Key="AuthenticationType">Bearer</Item>
    
  5. Change or add the UseClaimAsBearerToken to bearerToken, as follows. The bearerToken is the name of the claim that the bearer token will be retrieved from (the output claim from SecureREST-AccessToken).

    <Item Key="UseClaimAsBearerToken">bearerToken</Item>
    
  6. Ensure you add the claim used above as an input claim:

    <InputClaim ClaimTypeReferenceId="bearerToken"/>
    

After you add the above snippets, your technical profile should look like the following XML code:

<ClaimsProvider>
  <DisplayName>REST APIs</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="REST-GetProfile">
      <DisplayName>Get user extended profile Azure Function web hook</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://your-account.azurewebsites.net/api/GetProfile?code=your-code</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">Bearer</Item>
        <Item Key="UseClaimAsBearerToken">bearerToken</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="bearerToken"/>
      </InputClaims>
      ...
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

Using a static OAuth2 bearer

Add the OAuth2 bearer token policy key

To configure a REST API technical profile with an OAuth2 bearer token, obtain an access token from the REST API owner. Then create the following cryptographic key to store the bearer token.

  1. Sign in to the Azure portal.
  2. Make sure you're using the directory that contains your Azure AD B2C tenant. Select the Directory + subscription filter in the top menu and choose your Azure AD B2C directory.
  3. Choose All services in the top-left corner of the Azure portal, and then search for and select Azure AD B2C.
  4. On the Overview page, select Identity Experience Framework.
  5. Select Policy Keys, and then select Add.
  6. For Options, choose Manual.
  7. Enter a Name for the policy key. For example, RestApiBearerToken. The prefix B2C_1A_ is added automatically to the name of your key.
  8. In Secret, enter your client secret that you previously recorded.
  9. For Key usage, select Encryption.
  10. Select Create.

Configure your REST API technical profile to use the bearer token policy key

After creating the necessary key, configure your REST API technical profile metadata to reference the bearer token.

  1. In your working directory, open the extension policy file (TrustFrameworkExtensions.xml).
  2. Search for the REST API technical profile. For example REST-ValidateProfile, or REST-GetProfile.
  3. Locate the <Metadata> element.
  4. Change the AuthenticationType to Bearer.
  5. Change the AllowInsecureAuthInProduction to false.
  6. Immediately after the closing </Metadata> element, add the following XML snippet:
    <CryptographicKeys>
       <Key Id="BearerAuthenticationToken" StorageReferenceId="B2C_1A_RestApiBearerToken" />
    </CryptographicKeys>
    

The following is an example of a RESTful technical profile configured with bearer token authentication:

<ClaimsProvider>
  <DisplayName>REST APIs</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="REST-GetProfile">
      <DisplayName>Get user extended profile Azure Function web hook</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://your-account.azurewebsites.net/api/GetProfile?code=your-code</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">Bearer</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="BearerAuthenticationToken" StorageReferenceId="B2C_1A_RestApiBearerToken" />
      </CryptographicKeys>
      ...
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

API key authentication

API key is a unique identifier used to authenticate a user to access a REST API endpoint. The key is sent in a custom HTTP header. For example, the Azure Functions HTTP trigger uses the x-functions-key HTTP header to identify the requester.

Add API key policy keys

To configure a REST API technical profile with API key authentication, create the following cryptographic key to store the API key:

  1. Sign in to the Azure portal.
  2. Make sure you're using the directory that contains your Azure AD B2C tenant. Select the Directory + subscription filter in the top menu and choose your Azure AD B2C directory.
  3. Choose All services in the top-left corner of the Azure portal, and then search for and select Azure AD B2C.
  4. On the Overview page, select Identity Experience Framework.
  5. Select Policy Keys, and then select Add.
  6. For Options, select Manual.
  7. For Name, type RestApiKey. The prefix B2C_1A_ might be added automatically.
  8. In the Secret box, enter the REST API key.
  9. For Key usage, select Encryption.
  10. Select Create.

Configure your REST API technical profile to use API key authentication

After creating the necessary key, configure your REST API technical profile metadata to reference the credentials.

  1. In your working directory, open the extension policy file (TrustFrameworkExtensions.xml).
  2. Search for the REST API technical profile. For example REST-ValidateProfile, or REST-GetProfile.
  3. Locate the <Metadata> element.
  4. Change the AuthenticationType to ApiKeyHeader.
  5. Change the AllowInsecureAuthInProduction to false.
  6. Immediately after the closing </Metadata> element, add the following XML snippet:
    <CryptographicKeys>
        <Key Id="x-functions-key" StorageReferenceId="B2C_1A_RestApiKey" />
    </CryptographicKeys>
    

The Id of the cryptographic key defines the HTTP header. In this example, the API key is sent as x-functions-key.

The following is an example of a RESTful technical profile configured to call an Azure Function with API key authentication:

<ClaimsProvider>
  <DisplayName>REST APIs</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="REST-GetProfile">
      <DisplayName>Get user extended profile Azure Function web hook</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://your-account.azurewebsites.net/api/GetProfile?code=your-code</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">ApiKeyHeader</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="x-functions-key" StorageReferenceId="B2C_1A_RestApiKey" />
      </CryptographicKeys>
      ...
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

Next steps