Sign-up and sign-in with Digital Ocean using Azure AD B2C

This article describes how to add authentication for a Digital Ocean account to an Azure AD B2C custom policy.


The following diagram illustrates the authentication flow for a Digital Ocean account to an Azure AD B2C custom policy.

The authentication flow requires an Azure function that retrieves claims for the authenticated user.

For information about Digital Ocean and OAuth 2.0, see


  1. If you don’t already have one, then you must create an Azure AD B2C tenant that is linked to your Azure subscription.
  2. Prepare your Azure AD B2C tenant by creating the token signing and encryption keys and creating the Identity Experience Framework applications.
  3. Download one of the starter packs for Azure AD B2C from Microsoft’s GitHub repository.

Create the Azure function

  1. Create a C# function containing the following code. This implements a GetDigitalOceanClaims function that retrieves flattened claims for the authenticated user. Then publish this C# function to a function app.
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace SignInWithDigitalOcean
    public static class GetDigitalOceanClaims
        private static readonly HttpClient InnerClient = new HttpClient();

        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest request,
            ILogger logger)
            if (!request.Headers.TryGetValue("Authorization", out var authorizationHeaderValues))
                logger.LogError("The Authorization header is missing");
                return new BadRequestResult();

            if (authorizationHeaderValues.Count > 1)
                logger.LogError("The Authorization header is invalid");
                return new BadRequestResult();

            var authorizationHeaderValue = authorizationHeaderValues[0];
            var authorizationHeaderValueParts = authorizationHeaderValue.Split(' ');

            if (authorizationHeaderValueParts.Length != 2 || !authorizationHeaderValueParts[0].Equals("Bearer", StringComparison.OrdinalIgnoreCase))
                logger.LogError("The Authorization header is invalid");
                return new BadRequestResult();

            var innerRequest = new HttpRequestMessage(HttpMethod.Get, "");
            innerRequest.Headers.Authorization = new AuthenticationHeaderValue(authorizationHeaderValueParts[0], authorizationHeaderValueParts[1]);
            var innerResponse = await InnerClient.SendAsync(innerRequest);

            if (innerResponse.StatusCode != HttpStatusCode.OK)
                return new InternalServerErrorResult();

            var innerResponseModel = await innerResponse.Content.ReadAsJsonAsync<DigitalOceanClaimsResponseModel>();

            var responseModel = new
                id = innerResponseModel.Account.Uuid,
                email = innerResponseModel.Account.Email

            return new OkObjectResult(responseModel);

The model classes are implemented as follows.

using Newtonsoft.Json;

namespace SignInWithDigitalOcean
    public class DigitalOceanClaimsResponseModel
        public DigitalOceanAccountModel Account { get; set; }

    public class DigitalOceanAccountModel
        public string Uuid { get; set; }

        public string Email { get; set; }

The ReadAsJsonAsync extension method is implemented as follows.

using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace SignInWithDigitalOcean
    public static class HttpContentExtensions
        public static async Task<T> ReadAsJsonAsync<T>(this HttpContent content)
            if (content == null)
                return default;

            var value = await content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<T>(value);

Configure a Digital Ocean application

  1. Log in to
  2. On the Applications & API page, select OAuth Applications and then select Register OAuth Application.
  3. In the Register a new OAuth application dialogue, enter the following fields and then select Register OAuth Application:
    1. Name
    2. Homepage URL
    3. Description
    4. Callback URL: Enter either if you use the built-in domain or https://your-domain-name/ if you use a custom domain for the Callback URL field. Replace your-tenant-name with your tenant name and your-domain-name with your custom domain.
  4. On the Applications & API page, in the OAuth Applications tab, select More for the new application and then select View.
  5. On the OAuth Application Details page, copy the Client ID and Client Secret fields.

Add the client secret for the Digital Ocean application as a policy key

  1. Sign in to the Azure AD B2C portal.
  2. Select Identity Experience Framework.
  3. Select Policy keys.
  4. Select Add.
  5. In the Create a key section, enter the following fields and then select Create:
    1. Options: Manual
    2. Name: DigitalOceanClientSecret
    3. Secret: Paste the Client Secret field that was copied in the previous section.

Configure Digital Ocean as an identity provider

  1. Open the TrustFrameworkExtensions.xml file.
  2. Find the ClaimsProviders element. If it doesn’t exist, then add it to the TrustFrameworkPolicy element.
  3. Add the following ClaimsProvider element to the ClaimsProviders element. Replace your-digital-ocean-client-id with the Client ID field that was copied in the Configure a Digital Ocean application section. Replace your-function-app-name with the function app name that was created in the Create the Azure function section.
  <DisplayName>Digital Ocean</DisplayName>
    <TechnicalProfile Id="DigitalOcean-OAuth2">
      <DisplayName>Digital Ocean</DisplayName>
      <Protocol Name="OAuth2" />
        <Item Key="client_id">your-digital-ocean-client-id</Item>
        <Item Key="authorization_endpoint"></Item>
        <Item Key="AccessTokenEndpoint"></Item>
        <Item Key="ClaimsEndpoint"></Item>
        <Item Key="HttpBinding">POST</Item>
        <Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item>
        <Item Key="UsePolicyInRedirectUri">false</Item>
        <Key Id="client_secret" StorageReferenceId="B2C_1A_DigitalOceanClientSecret" />
        <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
        <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="" AlwaysUseDefaultValue="true" />
        <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="id" />
        <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
        <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />

Add a user journey

  1. Open the TrustFrameworkBase.xml file.
  2. Copy the UserJourney element that includes Id="SignUpOrSignIn".
  3. Open the TrustFrameworkExtensions.xml file and find the UserJourneys element. If it doesn’t exist, then add it to the TrustFrameworkPolicy element.
  4. Paste the UserJourney element that was copied in step 2 to the UserJourneys element and replace the Id attribute for this UserJourney element from "SignUpOrSignIn" to "DigitalOceanSignUpOrSignIn".

Add the identity provider to the user journey

  1. Add the claims provider that was configured in the Configure Digital Ocean as an identity provider section to the user journey that was added in the previous section.
<OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
    <ClaimsProviderSelection TargetClaimsExchangeId="DigitalOceanExchange" />

<OrchestrationStep Order="2" Type="ClaimsExchange">
    <ClaimsExchange Id="DigitalOceanExchange" TechnicalProfileReferenceId="DigitalOcean-OAuth2" />

Configure the relying party policy

  1. Open the SignUpOrSignIn.xml file.
  2. Replace the ReferenceId attribute for the DefaultUserJourney element from "SignUpOrSignIn" to "DigitalOceanSignUpOrSignIn".
  <DefaultUserJourney ReferenceId="DigitalOceanSignUpSignIn" />

Upload and test the custom policy

  1. Upload all policy files in the following order to your Azure AD B2C tenant:
    1. TrustFrameworkBase.xml
    2. TrustFrameworkLocalization.xml
    3. TrustFrameworkExtensions.xml
    4. SignUpOrSignIn.xml
  2. Test the B2C_1A_signup_signin policy from your Azure AD B2C tenant.
[mailpoet_form id="1"]

Other Recent Blogs

Microsoft Teams IP Phones and Intune Enrollment

Microsoft Teams provides a growing portfolio of devices that can be used as desk and conference room phones. These IP phones run on Android 8.x or 9.x and are required to be enrolled in Intune. By default, these devices are enrolled as personal devices, which is not ideal as users should not be able to enrol their own personal Android devices.

Read More »

Level 9, 360 Collins Street, 
Melbourne VIC 3000

Level 2, 24 Campbell St,
Sydney NSW 2000

200 Adelaide St,
Brisbane QLD 4000

191 St Georges Terrace
Perth WA 6000

Level 10, 41 Shortland Street

Part of

Arinco trades as Arinco (VIC) Pty Ltd and Arinco (NSW) Pty Ltd. © 2023 All Rights Reserved Arinco™ | Privacy Policy | Sustainability and Our Community
Arinco acknowledges the Traditional Owners of the land on which our offices are situated, and pay our respects to their Elders past, present and emerging.

Get started on the right path to cloud success today. Our Crew are standing by to answer your questions and get you up and running.