Determine your Dynamics 365 portal data center

When you deploy a portal for Dynamics 365 you always want it located as close to your Dynamics 365 instance physically so that the latency for all communications between the portal and Dynamics 365 is as low as possible. With Microsoft managing the portal provisioning they take care of this for you. You still may want to determine the location for hosting of other services that will communicate with your portal, like when your looking at deploying a companion web app for your portal it would be ideal if it is the same data center as your portal.

You can quickly determine your major data center region just by looking at the address to your Dynamics 365 instance. The following link has a listing of all current major regions – Discover the URL for your organization using the Organization Service.  However within these major regions are regional data centers. For instance, https://*.crm.dynamics.com (North America which should actually be called USA/Mexico now since there is a region for Canada) has 3 different regional data centers and they are even creating secondary data centers regionally.  Within North America (or USA/Mexico) you could be in West US, Central US, East US, or even East US2.  Within CRM3 (Canada) you could be in Canada Central or Canada East as your primary data center. You can see all the Azure datacenter locations in the following link – Azure Datacenter locations.

Previous ways to determine your data center have involved spinning up an Azure VM and moving it through regions while doing latency tests.  You can also use a IP locator service to help you determine provided the IP address you testing has the proper location data registered with it (this sometimes can give false information as IP addresses can be re-routed to different regions).  Another way which the guys over at Peak Engagement blogged about is using the debug information page which reveals information about your Dynamics instance including the server name, database server, database name and much more.  If you look at patterns you may notice that the names of the servers are based on those regional data centers.

The Dynamics 365 portal has something similar but you can even use this technique on any Dynamics 365 portal without even being the owner of that site.  On every request response to the portal if you inspect the headers you will notice 2 additional response header keys added specifically for the Dynamics 365 portal, x-ms-portal-app and x-ms-request-id. The x-ms-request-id is just a unique GUID for each request, likely exposed to help assist with debugging. The x-ms-portal-app is a value for the site itself, it remains constant through all requests. Taking a look at the value found, there is the site GUID which is the GUID of the Azure Web App and then appended to that is a data center code.

You can easily get to this yourself without even being logged into the portal. The request headers are available on all requests. To look at this value open your browsers developer tools (F12), then select the network tab, open the details of any request and view the response headers. Below is a screenshot of Chrome’s developer tools highlighted with the navigation tips.

Below is a list of the data center region codes found on Dynamics 365 portals from the portals I have checked thus far.

  • EUw – West Europe
  • EUn – North Europe
  • USw – West US
  • GCv – US Government Cloud Virginia
  • GCi – US Government Cloud Iowa
  • USe2 – East US2
  • CAc – Canada Central
  • AUse – Australia Southeast

This is not an exhaustive list, if you come across others then feel free to drop a note in the comments.

You can now use this information to help you when picking a hosting location for a companion app as this region should be in same as your Dynamics 365 instance so you can attempt to get the best performance between applications and the backend Dynamics 365 instance.

Note there are instances where the Dynamics 365 instance and the portal will not be located in the same data center. This is not often the case but instances of this have seen that East US can host Dynamics 365 and East US2 can host the portal, this type of setup might also occur in other locations.

Configure ADXStudio Portals and CRM portals with Azure AD B2C

Azure Active Directory B2C is a new Azure service that is targeted at helping your organization utilize consumer based identities within your sites and applications. This is a guide covering setting up ADXStudio Portals version 7 and CRM portals v8.1 with Azure AD B2C as an identity provider through configuration.  As well discuss some of the additional customizations that can be made to the ADXStudio Portal v7 MasterPortal code base to further enhance the user experience.

A recent update to Azure AD B2C policies has allowed ADXStudio Portals and CRM portals to work with Azure AD B2C via configuration.  To learn more about the technical change please view Azure AD B2C Now Supports ADXStudio Portal v7.

CRM portals v8.x customization is limited and therefore the user experience that the customizations below outline with Azure AD B2C cannot be completely implemented.  CRM portals v8.2 is expected to support Azure AD B2C natively in the Fall release or in a future monthly update.  All configuration based settings mentioned apply for ADXStudio and CRM portals interchangeably.

Note that while you can configure B2C with CRM portals it is completely unsupported and not recommended by Microsoft. The concern is that when support is added to CRM portals if you were previously using B2C that the implementation might not be compatible with your existing users. Therefore it is advised that you do not configure B2C with CRM portal until it is released directly as a feature of the product. The date for this has also moved to unknown, there was discussion on this coming shortly in 8.2, but that has not be committed to. If you wish to implement Azure AD B2C then you should use the latest version of ADXStudio Portals.

The benefit of using Azure AD B2C is moving the authentication of your users to a common secure global service that be consumed be various different application platforms because of its standard based implementation of OpenID Connect. This allows your users to have a single identity with a common user experience across your portfolio of applications. ADXStudio Portals and CRM portals with its implementation of ASP.NET Identity built on the OWIN Framework supports OpenID Connect since version 7.0.0020 with providers like Azure AD B2C.

To get started you will need to create an Azure AD B2C directory which is completely free up to 50,000 authentications per month. Once you have your Azure AD B2C directory you have the ability to enable various social identity providers like Facebook, Google, LinkedIn, Amazon and Microsoft Account for you users to use. You can also enable users without a social identity account to create local users via email address or username. To learn more about creating a directory and setting up social providers via the guide here.

One of the unique functions of Azure AD B2C is that it has the concept of policies. The policies allow you to segment configurations of your identity service, providing flexibility per application, process or however you decide to use policies.  Policies allow you to customize the branding, as to what might be collected during sign up or the claims that are returned to an application. Based on how the ADXStudio Portal and CRM portals function with identity providers through configuration it is best implemented with a “Sign Up and Sign In” policy instead of separate policies for “Sign In” and “Sign Up”.

For the ADXStudio Portal or CRM portals to consume B2C we will need to list it as an application in the B2C settings.

  1. Navigate to Azure AD B2C tenant and then the settings for the directory in the Azure Portal and select Applications, then Add.
  2. Add your application name, enable Web App / Web API, and enter your reply URL (this must be HTTPS and it only needs to be your ADX portal root URL).
  3. Click the Create button.
  4. Once the application is created, select it and you should see an Application ID. Copy this value and save it.

To configure OpenID Connect for ADXStudio Portal or CRM portals we need to map the functionality of the CreateOptionsFromPolicy method in the GitHub sample for .NET Web App Startup.Auth.cs to the portal site settings documented here for ADXStudio Portals and here for CRM portals.

Adding a new identity provider with ADXStudio Portal or CRM portal is must be done via the CRM GUI, outlined below are the necessary site settings for Azure AD B2C.

The settings all follow the format of Authentication/OpenIdConnect/AzureADB2C/[setting_name]. The text AzureADB2C can be replaced with your desired provider name, the label seen on the portal is configured through the caption setting.

Authentication/OpenIdConnect/AzureADB2C/AuthenticationType
The value is the name of your B2C policy for Sign Up and Sign In.
Sample Value: B2C_1_SuSi

Authentication/OpenIdConnect/AzureADB2C/MetadataAddress
You can obtain this value by selecting your policy and copying the metadata endpoint address at the top of the panel.
Sample Value: https://login.microsoftonline.com/adxb2c.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_SuSi

b2c_policy

Authentication/OpenIdConnect/AzureADB2C/Authority
You can obtain this value by navigating to your Metadata Address and copying the value of issuer
Sample Value: https://login.microsoftonline.com/52f15a3d-fac9-447f-832b-79e4fc16bff6/v2.0/

b2c_issuer

Authentication/OpenIdConnect/AzureADB2C/ClientId
The value is the Application ID that you saved when setting up the application in the previous steps.
Sample Value: e48b78ef-e274-4480-a3d5-621138ae1b47

Authentication/OpenIdConnect/AzureADB2C/RedirectUri
This value applies to both RedirectUri and PostLogoutRedirectUri. It should be the root URL to your ADX portal.
Sample Value: https://b2cadx.local.adoxio.com

Authentication/OpenIdConnect/AzureADB2C/PostLogoutRedirectUri
This value applies to both RedirectUri and PostLogoutRedirectUri. It should be the root URL to your ADX portal.
Sample Value: https://b2cadx.local.adoxio.com

Authentication/OpenIdConnect/AzureADB2C/Scope
Value: openid

Authentication/OpenIdConnect/AzureADB2C/ResponseType
Value: id_token

Authentication/OpenIdConnect/AzureADB2C/NameClaimType
Value: name

Authentication/OpenIdConnect/AzureADB2C/Caption Optional
This can be set to whatever you would like the button text to read on the Sign In and Register pages of the portal. This value is optional.
Sample Value: Azure AD B2C

Once you have completed all the site settings outlined above associated to your ADX portal website then you should be able to restart the portal application and see the new provider listed under external account.

ADXStudio Portals Sign In:
adx_signin

CRM portals Sign In:
crmportal_signin

You can now test your registration and sign in flows. The nice thing about the Sign Up and Sign In policy and the portal is it will handle that detection as part of its out of the box configuration. All of the other ADXStudio Portals or CRM portal authentication settings can be used and applied to the site as normal.

The following customizations only applies to ADXStudio Portals.

With the out of box code in ADXStudio Portals login controller the logoff or sign out function will only sign you out from the ADX Portal. To modify this functionality you just need to update the Logoff HTTP GET and POST methods in LoginController.cs. This controller can be found in the MasterPortal code base Areas\Account\Controllers folder.

// GET: /Login/LogOff
[HttpGet]
public ActionResult LogOff(string returnUrl)
{
	if (HttpContext.Request.Url != null && !returnUrl.Contains(HttpContext.Request.Url.Authority))
	{
		returnUrl = $"{HttpContext.Request.Url.Scheme}://{HttpContext.Request.Url.Authority}{returnUrl}";
	}

	var authTypes = AuthenticationManager.GetAuthenticationTypes();

	AuthenticationManager.SignOut(new AuthenticationProperties { RedirectUri = returnUrl }, authTypes.Select(t => t.AuthenticationType).ToArray());
	return Redirect(!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl) ? returnUrl : "~/");
}

The changes here are to ensure that the return URL passed to Azure B2C is a includes the full site URL and not just the relative path. Azure B2C checks this return URL against what was configured in the application settings to ensure it includes the same root URL.   Additional the code to tell ASP.NET Identity OWIN to sign out not only of the portal but also Azure B2C is to modify the SignOut method of the AuthenticationManager to include the authentication types as a parameter. This causes OWIN to process not only the ADX applicaiton cookie but call the associated Azure B2C logoff method which will remove the Azure B2C cookie as well.

Note – you may also modify the ReturnUrl methods in Helpers\UrlHelper.cs to output a full qualified URL as the return URL instead of modifying the URL in the LogOff HTTP GET method.

The following is the change to the HTTP POST method, no return URL is needed, just the Authentication Types added to the SignOut parameters.

// POST: /Login/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
	var authTypes = AuthenticationManager.GetAuthenticationTypes();

	AuthenticationManager.SignOut(authTypes.Select(t => t.AuthenticationType).ToArray());
	return Redirect("~/");
}

The other changes you would be able to make in the code is mapping claims to CRM properties so that the profile is auto populated. Though you may need to consider a more complex implementation so that all CRM modifications of certain attributes are sync’d back to the Azure AD B2C attribute store. If you are interested then check out the Graph API documentation. For a less complex implementation that does not require complex attribute mapping, you could leave contact profile data collection just to CRM/portal and not collect any additional claims on the Azure B2C side.

If you want to at least ensure the email from Azure B2C is mapped to the CRM Contact email address then you can modify the ExternalLoginCallback method in the LoginController.cs and add lines 8 – 11 highlighted in the following code:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();

if (loginInfo == null)
{
	return RedirectToAction("Login");
}

if (string.IsNullOrEmpty(loginInfo.Email))
{
	loginInfo.Email = loginInfo.ExternalIdentity.Claims.FirstOrDefault(a => a.Type == "emails")?.Value;
}

This is necessary due to the AuthenticationManager.GetExternalLoginInfoAsync() method only looking for http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress as the claim type name it would get for email.  Note B2C has been modifying the email claim name recently so you may need to update the Type condition to match what is current.

A last tip, if you plan to only use Azure B2C then it might make sense for your users to skip the portal sign in page and go directly to Azure B2C. This can be done using an out of box site setting Authentication/Registration/LoginButtonAuthenticationType. Simply set this site setting to same value as the site setting Authentication/OpenIdConnect/AzureADB2C/AuthenticationType and the sign in button in headers that utilize the UrlHelper method (default out of box non-liquid based) will forward directly to Azure B2C.

Azure AD B2C Now Supports ADXStudio Portals v7

Azure Active Directory B2C is a new Azure service that is targeted at helping your organization utilize consumer based identities within your sites and applications.  Until recently ADXStudio Portals version 7 required custom code modification to properly support Azure B2C as a login provider but now with a recent change by the Azure AD B2C team it can be configured directly through site settings.

ADXStudio Portals implementation of ASP.NET Identity is perhaps one of the best identity implementations in a CMS.  It supports such a wide array of protocols and token formats making it easy to integrate with various identity platforms and supports a single profile with many identities.  Previously ADXStudio Portal integrated with Azure ACS (Access Control Service) which provided a way to integrate with social identity providers like Google, Facebook or Microsoft Windows Live ID (at the time) if you wanted a common STS that managed all your consumer identity providers.  The ADXStudio Community site actually still uses Azure ACS for its authentication.  Azure ACS is being retired and replaced by various new Azure services (creating new ACS directories has been blocked, but existing directories continue to function), for the consumer identity side that replacement is Azure AD B2C which comes with a wealth of new features that many have been long asking for in Azure ACS.

With ADXStudio Portals implementation of standards based protocols like OpenID Connect and the same standards based protocols implemented in Azure AD B2C you would think it was an easy match.  Unfortunately ADXStudio Portals v7 ASP.NET Identity OWIN implementation expected a certain claim to be populated and Azure AD B2C was not supporting that claim…until recently.

The claim required by ADXStudio Portals ASP.NET Identity:

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

And until recently Azure AD B2C would populate that claim with “Not supported currently. Use oid claim.”.  Since ASP.NET Identity mapped the nameidentifier claim to the login key and ADXStudio Portal the login key to the username field in CRM, no matter who you logged in as on the Azure AD B2C side you would always be the same contact in ADX/CRM.  The error in the nameidentifier claim from Azure AD B2C was directing the application to instead use the OID claim:

http://schemas.microsoft.com/identity/claims/objectidentifier

And to use this claim value as the username, but this required some custom code to override the existing ASP.NET Identity logic within the ADXStudio Portal login controller callback method.

Now new Azure AD B2C policies are populating nameidentifier with the same value as objectidentifier which allows ADXStudio Portal to be configured with a Sign Up and Sign In policy just through portal site settings.  There is still some functionality that will required to you modify the ADX code base, sign out that including signing out of Azure AD B2C, if you want to incorporate profile edits that sync with CRM attributes, and if you wanted to use separate policies from registration and sign in.

Note, if you have existing Azure AD B2C tenant with existing policies, the nameidentifier claim may still not show in those policies.  Re-creating your policies should enable the nameidentifier claim.

To learn more about configuring ADXStudio Portals with Azure AD B2C I will follow this up with a guide shortly showing the configuration end to end.