Azure, C#, Web

Connecting Azure AD and Azure AD B2C to IdentityServer4

3 min read

I’ve been playing with IdentityServer4 lately and I wanted to share you guys the findings I’m finding while I am playing with it. IdentityServer4 for the ones who don’t know it, is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core 2. You can read all about it here.

In today’s post, I would like to show you how you can connect Azure AD and Azure AD B2C to IdentityServer4 as external providers. When doing so, IdentityServer becomes a federated gateway. Both implementation are similar, however, Azure AD and Azure AD B2C have specificities that are particular to them.

Connecting to Azure AD

We can connect Azure AD to IdentityServer through an external OpenIdConnect provider. To do that, you will need to add it to the authorization pipeline.

The key points in this code snippet are the following:

Authority: this is the Azure AD endpoint to which you will be redirected when you connect.
ClientId:  Application ID obtained from the Azure portal
Tenant: Obtained from the Azure portal. Select ‘Endpoints’ from the ‘App registrations’ blade and use the GUID in any of the URLs), e.g. da41245a5-11b3-996c-00a8-4d99re OR it is your *.onmicrosoft.com uri
ClientSecret: Obtained when creating an application key

IdentityServer is able to get back the information from the external providers through an external cookie. It is thus important to set the Scheme to IdentityServerConstants.ExternalCookieAuthenticationScheme.

Pitfalls

Cannot cast Newtonsoft.Json.Linq.JArray to Newtonsoft.Json.Linq.JToken.

When getting redirected back, you will see in your logs, when you get back to your client, the following:

This is because the name claim is there twice.
Remove the ClaimTypes.Name from the claims as the value in this claim for Azure AD is your email address

You can do that in the OnTokenAuthorize event in the OpenId pipeline (OpenIdConnectOptions.Events.OnTokenAuthorize)

.AspNetCore.Correlation. state property not found.

You may get the following error in the remote authentication when you are redirected back to IdentityServer

This error occurs if you add more than one OpenIdConnect provider to your authorization middleware pipeline. To remedy that, just set the callbackpath to something else like “/signin-oidc-azureXXX”.  Remember to make sure to reflect that path in your reply url, located in the application setting in your Azure AD application.

Connecting to Azure AD B2C

Azure AD B2C follows the Azure AD approach. You can connect to it by also using the OpenIdConnect provider. Azure AD B2C, however, uses policies for sign-in.

You will need to append that policy to your Authority EndPoint so that you can use that policy for the sign-in.

Authority: https://login.microsoftonline.com/tfp/{Tenant}/{Policy}/v2.0

Mapping Azure AD B2C Groups to the Security Role claim

If you want to map Azure B2C Groups to the Role claim, you need to use the Graph API for that. Currently they aren’t automatically added to the claims when you authenticate (make this possible by vouching on the feedback forum here).

You can have a base start for the B2CGraphClient by using the implementation showed in the Azure AD quickstart on GitHub. To setup the rights for the GraphAPI to be able to connect to your Azure AD B2c, follow this guide.

To be able to query the groups a user is associated to you need to query the member attribute of the user. You can do that by adding a new method to your B2CGraphClient class:

Then in your OnTokenAuthorize event in the OpenIdConnect authorization middleware handler, you will need to add a new role claim to the claims principal for the user. Here’s a snippet on how you can do that:

Edit 2018-09-26: added the authenticationtype to the claims identity

Make sure that in your Client, you properly map the role claim to the security role claim so that it can be used in the the authorize handler for roles

Final words

I’m always looking to improve, so if you believe there are better ways, don’t be shy to contact me; I’m always happy to learn.