Add Apple ID Login to your Xamarin Forms B2C Authentication

Apps that use a third-party or social login service (such as Facebook Login, Google Sign-In, Sign in with Twitter, Sign In with LinkedIn, Login with Amazon, or WeChat Login) to set up or authenticate the user’s primary account with the app must also offer Sign in with Apple as an equivalent option. A user’s primary account is the account they establish with your app for the purposes of identifying themselves, signing in, and accessing your features and associated services.

If your app has been rejected by Apple recently than the above paragraph is most likely the reason. The problem is when using Azure ADB2C for logging in and offering your users the possibility of social log-in than now Apple wants you to use Apple-ID as well. Is this possible with Azure ADB2C? Short answer: yes. This article shows you how.

You basically need three things from Apple to get the whole thing running. First of all you need an identifier for your app. This identifier probably exists already. Secondly you need a service id and last but not least you need a key to sign your requests.

All things can be accomplished by using https://developer.apple.com. Be aware that a paid apple developer id is necessary for this to be done.

Log In and go to Certificates, Identifiers and Profiles and then navigate to Identifiers and click + to create a new App-ID or select an existing App-ID.

During the next step enter a Description and an explicit Bundle ID and follow the recommendation to use a reverse-domain name style.

Then scroll down and tick Sign In with Apple.


Click Continue, check all entries and finally register your App-ID.

In the next step you need to create a Service ID for web authentication. This is done as before, just select Services IDs instead of App IDs and enter the data.


Please follow the recommendation to use reverse-domain name style and add service suffix or as you prefer and click Continue and Register. After the registration enter your newly created Services ID and configure the Sign In with Apple Options.


Select your previously created or used App-ID and add at least one Website URL and one Callback URL by clicking +

In our special case we would use example.com in the Domains and Subdomains entry field and https://tenant.b2clogin.com/tenant.onmicrosoft.com/oauth/authresp in the Return URLs field. Please replace tenant in the string with the name of your Azure ADB2C tenant.

To accomplish the last step click on Keys and + to create a new one. Give the key a meaningful name and select Sign in with Apple and configure.

During the configuration please select the app you created or used during the first step and click continue and save until you can register the key. This key plays an important role during the authentication process and can only be downloaded once – so keep the key in a safe place. You will surely need it within the next 6 months because this is the maximum timespan Apple allows for getting authentication services with the same token.

Generally speaking the authentication process runs over a few endpoints we should configure in our own file:

{
    "issuer": "https://appleid.apple.com",
    "authorization_endpoint": "https://appleid.apple.com/auth/authorize",
    "token_endpoint": "https://appleid.apple.com/auth/token",
    "jwks_uri": "https://appleid.apple.com/auth/keys"
}

This file defines the OpenID endpoints being called during the authentication process. First the authorization_endpoint is being called. This endpoint asks for your username and password and walks on to the keys endpoint which delivers an authorization_code for receiving a token from the token_endpoint. This token is thereafter used to authorize calls in the name of your app.

Place this endpoint configuration to a webserver and take care that the path where the file is placed ends with …/.well-known/openid-configuration.

With all settings in place we just have to sign the required JWT token (stated below) with the previously downloaded key. It is highly important that you follow EXACTLY the specifications below regarding the encryption algorithm namely ES256. Otherwise you will get an error AADB2C90289: We encountered an error connecting to the identity provider. Please try again later.

The required JWT token is defined as stated below:

{
  "alg": "ES256", //encryption algorithm
  "typ": "JWT" //type namely JWT
}.{
  "sub": "com.yourcompany.app1", //app namespace
  "nbf": 1560203207,	//not before ticks
  "exp": 1560289607,	//valid until ticks
  "iss": "ABC123DEFG",	//TeamID of your apple developer account
  "aud": https://appleid.apple.com //audience = Apple
}.[Signature]

Although there are a few webservices out there for signing the JWT I have created a small .NET Core console app here on GitHub which does all the magic for you. Just replace the following values within Program.cs and execute.

static string Sign()
{
    string audience = "https://appleid.apple.com";
    string issuer = ""; //team 
    string subject = ""; //service
    string p8key = ""; //key
}

Copy the return key to safe place and then let’s go to Azure ADB2C and bring the whole thing to an end.

First open your ADBC2 Tenant Management Blade and click Identity Providers and add a new OpenID Connect provider. Fill the name field as you like and copy the path to the Metadata url we created before for example https://www.example.com/.well-known/openid-configuration.


As Client ID you should use the service we created in the steps before on the Apple Developer Portal for example com.example.exampleservice.

For the Client secret you use the encrypted output of your JWT token, the Scope says openid and for the Response type we use code and the Response mode should be form_post in this configuration situation with Apple Id. For the claims mapping (not on the picture but below) you can enter sub for User ID and Display name.

Thereafter go to your respective user flows, select the desired one and select your created Open ID provider under Identity providers.

Please take special care on how the Sign In with Apple Id button looks like. This problem is solved in another blog post.