In this article, I would like to give you an overview of how to use Azure B2C authentication in Event Management portals as well as how to fix most of the issues and problems you might face during the configuration. Event management portals configuration is a bit different from power portals as you also need to configure angular frontend. I will also provide information on which angular modules are responsible for implementing b2c authentication as well as how backend process the requests..
Let’s briefly discuss why you might need Azure B2C authentication. Let’s assume you want to allow your users to manage sessions that they wish to attend or just restrict the possibility to register without an approved e-mail address. This is where Azure B2C can help you and provide infrastructure to manage your users. If you never heard about Azure B2C before, please check the documentation: What is Azure Active Directory B2C? At first, I would like to give you a link to the official documentation: Setting up event management to work with AAD B2C. I don’t want to focus on the creation of necessary thinks as they are very well documented. However, I will provide screenshots of all my settings for you and try to explain topics that are not covered in the documentation. Let’s start.
This article describes the configuration for the new event management public API. To use the new event management public API, you need to register the web application and use emApplicationToken. You will find information on how to do it in the appropriate part of this article. Your environment.ts should contain useRestStack = true.
1. First of all, we need to create an Azure B2C tenant: Create an Azure Active Directory B2C tenant.
2. Register an application in Azure Active Directory B2C.
App ID URI should contain events. We need App ID URI to define the scope. Scope defined in the azure application should match the scope defined in our event management angular application. Below you can find scopes that I have for my app.
Please allow all API access you have as on the picture below
Now we have our app fully configured. The next step is to configure policies. Policies define how we create new users or restore passwords for existing ones. Please check how to create policies in the following article: Setting up event management to work with AAD B2C. Here are how I configure my policies:
As you see, I have two policies: 1. Password reset. 2. Sign up and sign in. Please see below the detailed configuration:
1. Password reset. (Properties)
2. Password reset. (Identity providers)
3. Password reset. (Claims)
4. Sign up and sign in (Properties 1)
5. Sign up and sign in (Properties 2)
6. Sign up and sign in (Identity providers)
7. Sign up and sign in (User attributes)
8. Sign up and sign in (Claims)
All properties are important. For example, if you will not choose to use User’s Object ID, then your event management process will not be able to process the token and raise the exception.
Once you’ve configured Azure B2C Tenant, Application, and Policies, you can switch to Angular frontend and configure environemnt.ts. Below you can find how the configuration looks for me:
/** * This is the configuration when using the portal-hosted approach. * The DeployToDynamics365Instance.ps1 script (located in Scripts/ directory) uses this configuration * when deploying this application to Portals. * * Please note: Please only change this file if you really know what you're doing. * The DeployToDynamics365Instance.ps1 script does not require any modifications to this file. */ export const environment = { /** * Enables/Disabled the production mode of Angular. * You can find more information about the production mode here: https://angular.io/api/core/enableProdMode */ production: true, /** * This field links to the version specified in the `package.json` file by default. There is no need to change this property. * However, if you prefer not to expose the version of the application, you can set it to `null`. **/ buildVersion: require('../../package.json').version, /** * The URL that points to the Event Management API endpoint (which is used to retrieve information of events and to make registrations). * If you're using the deprecated Event Management Portal API then you need to enter the URL of your Portals. * If you're using the new Event Management Public API then you need to enter the value from the `Endpoint` field that you * get after registering your web application. Additionally you need to append 'EvtMgmt/api/v2.0/'. * Note: The URL **must** have a trailing slash. **/ apiEndpoint: 'https://111111111111111111111.svc.dynamics.com/EvtMgmt/api/v2.0/', /** * Points to the URL where the localization files are stored in Portals. */ localizationEndpoint: 'localization/', /** * This endpoint is not required if you're serving the website from Portals. * Note: If you want to add static images to the Angular application, a new web file must be created in Portals. */ imagesEndpoint: '/', /** * This setting specifies which API is used. * If set to true then the new Event Management Public API is used. * If set to false then the deprecated Event Management Portal API is used. This API can only be used if you host on Portals. * Note: In order to use the new Event Management Public API you need to register your web application in CRM. */ useRestStack: true, /** * This token authenticates your web application against our Event Management Public API. * You can retrieve the application token by registering a new web application in CRM. * Note: This token is not required if you're using the deprecated Event Management Portal API. */ emApplicationtoken: '1111111111111111111111111', /** * This flag specifies whether user authentication is supported (meaning user can to register/sign-in). * If set to false then the application will not display a possibility sign-in or register. */ isAuthenticationEnabled: true, /** * Specifies whether you want to use **Azure Active Directory B2C identity management** for authentication. * If you want to use **Dynamics 365 Portals identity management** then this flag needs to be set to false. * Note: If AAD B2C is enabled then you need to configure the `aadB2CConfig` variable. */ useAadB2C: true, /** * The configuration for **Azure Active Directory B2C identity management**. */ aadB2CConfig: { authorityHost: 'eventmgtb2c.b2clogin.com', tenant: 'eventmgtb2c.onmicrosoft.com', clientID: 'b38c0dfd-8ac1-4644-849d-44d1e09211f3', signUpSignInPolicy: 'B2C_1_signupandsignin', b2cScopes: ['https://eventmgtb2c.onmicrosoft.com/events/registration'], redirectUri: 'http://localhost:4200' }, /** * This setting can be used to return mock objects instead of making real API calls. */ useMockData: false };
To get authority host, you need to open your sign up and sign-in policy and click run.
To complete the configuration and in case you use Event API 2.0, you also need to create Event Management web application configuration. Event API 2.0 created as a separate service, and you need to obtain an “emApplicationtoken” token to use it. Previously it was a LIQUID script and special plugin behind it; everything was hosted inside Dynamics 365 CE. Now we have a separated web service that requires a particular token.
More information you can find here: Using Events API. Now you have fully configured Azure B2C Authentication for Event Management Portals. Hoverwer something might not work. Let’s briefly review possible errors:
This application does not have sufficient permissions against this web resource.
Usually, this error happens when the scope defined in your Azure application doesn’t correspond to the scope defined in your angular application environment.ts file.
The AAD policy does not contain the required claim: $http://schemas.microsoft.com/identity/claims/objectidentifier. This is most probably caused due to a wrong configured AAD policy.
This error always happens when some of the required claims are not defined in the appropriate policy. Check your policy and mark appropriate claims.
Sometimes it is good to check Js console to find the error description.
Here is how the authenticated request looks like:
Here is how this request looks like from the Angular point of view. This code is from file user.rest.service.ts.
public getRegistrationsForUser(): Observable <myregistration[]> { return this.http.get<myregistration[]> (`${environment.apiEndpoint}${UserRestService.usersEndpoint}/authenticated/registrations`, true); }
The second argument for http.get is true, which means that as a part of this request, we need to send the authentication token. Implementation of the function which constructs the request can be found in HttpRestHelper.ts.
In case you want to add some more information about the user in the area, which is available only for registered users (e.g., my registrations). Simply use the Azure function, which will parse the authentication header and use data from it to request additional information from Dynamics CE and return some data back to the frontend. You can later call this azure function from the angular front-end.