Agenda:
Reviewing the Exercise – Collect a Loyalty Number from your Customers
Getting Started with Azure AD B2C Custom Policies
Setting up the Policy
Defining the Loyalty Number Claim
Configuring Profile Editing to Include the Loyalty Number
Configure Reading and Writing the Claim
Updating the User Journey
Relying Party Declaration Updates
Apidays New York 2024 - The value of a flexible API Management solution for O...
Azure AD B2C Webinar Series: Custom Policies Part 2 Policy Walkthrough
1. Azure AD B2C Webinar Series
Custom Policy Walkthrough
John Garland
VP Cloud Development & Instructor, Wintellect
Azure MVP, MCT, P-CSA
wintellect.com
@dotnetgator
Vinu Gunasekaran
Program Manager, Microsoft
Jas Suri
Program Manager, Microsoft
3. Date Time (PDT) Topic
20-Apr
21-Apr
2-3 PM
8-9 AM
Identity Protocols – OIDC, OAuth2
Recording: https://aka.ms/B2CWebinarRecordings
27-Apr
28-Apr
2-3 PM
8-9 AM
B2C & App Integration (with MSAL)
Recording: https://aka.ms/B2CWebinarRecordings
4-May
5-May
2-3 PM
8-9 AM
Custom Policies Part 1: Concepts with Take-Home Lab
Recording: https://aka.ms/B2CWebinarRecordings
11-May
12-May
2-3 PM
8-9 AM
Custom Policies Part 2: Policy Walkthrough
18-May
19-May
2-3 PM
8-9 AM
Custom Policies Part 3: Troubleshooting
Calendar of Previous & Upcoming Sessions
4. Azure AD B2C Webinar Series
Custom Policy Walkthrough
John Garland
VP Cloud Development & Instructor, Wintellect
Azure MVP, MCT, P-CSA
wintellect.com
@dotnetgator
Vinu Gunasekaran
Program Manager, Microsoft
Jas Suri
Program Manager, Microsoft
5. • Reviewing the Exercise – Collect a Loyalty Number from your Customers
• Getting Started with Azure AD B2C Custom Policies
• Setting up the Policy
• Defining the Loyalty Number Claim
• Configuring Profile Editing to Include the Loyalty Number
• Configure Reading and Writing the Claim
• Updating the User Journey
• Relying Party Declaration Updates
Agenda
Note – The content today assumes you are familiar with the prerequisite material outlined in the session description, including:
• What is Azure AD B2C
• Basic Azure AD B2C configuration and user flow creation
• Azure AD B2C Use Cases
Also, if you haven’t already, you may want to go back and watch the prior sessions in this series.
• https://aka.ms/B2CWebinarRecordings
6. • Create a custom policy that will:
• Allow new users to sign up or existing users to sign in
• Users will create credentials that are local to the application
• B2C user accounts should record a user’s Loyalty Number (grocery store points
club membership number)
• In order to keep the initial sign-up experience as simple as possible, the Loyalty
Number should be obtained progressively
• It is not collected when the user first signs up, but instead the policy should wait until the
user signs in a second time.
Exercise: Progressive Profiling
https://aka.ms/B2CWebinarLabs/
7. Getting Started with Azure AD B2C Custom Policies
https://docs.microsoft.com/azure/active-directory-b2c/custom-policy-get-started
• Create an Azure AD B2C tenant and link it to an Azure Subscription
• Define the Signing and Encryption Keys to be used by your policies
• Register the applications used to sign in local accounts
• Retrieve values that are used to allow your policies to work with Custom
Claims
• If you are working with external identity providers (such as Facebook),
register an application with the identity provider
8. Key Value
Tenant Name AzureADB2CWebinarSeries
Signing Key Name B2C_1A_TokenSigningKeyContainer
Encryption Key Name B2C_1A_TokenEncryptionKeyContainer
IdentityExperienceFramework App Client ID 11111111-1111-1111-1111-111111111111
ProxyIdentityExperienceFramework App Client ID 22222222-2222-2222-2222-222222222222
b2c-extensions-app Object ID 33333333-3333-3333-3333-333333333333
b2c-extensions-app Client ID 44444444-4444-4444-4444-444444444444
9. Initial Policy Setup
• Download or clone the
Custom Policy Starter Pack
• Create a workspace
• Update the policy files
with your Tenant ID
• Update the policy settings
• Create and reference a new
User Journey
• Test it out!
TrustFrameworkBase
TrustFrameworkExtensions
Progressive_Signup_SigninProfileEdit PasswordReset
App1 App2 App3
Relying Party Applications
10. • Policies can inherit from “parents” with the BasePolicy element
• Elements with similar ID’s are “merged”
• Locate the same ID, replace matching items
• Otherwise add
Inheritance with Azure AD B2C Custom Policies
11. Parent File:
<ClaimType Id="givenName">
<DisplayName>Given Name</DisplayName>
<DataType>string</DataType>
<UserHelpText>Your given name (also known as first name).</UserHelpText>
<UserInputType>TextBox</UserInputType>
</ClaimType>
Child File:
<ClaimType Id="givenName">
<DisplayName>Given Name Override</DisplayName>
</ClaimType>
Result:
<ClaimType Id="givenName">
<DisplayName>Given Name Override</DisplayName>
<DataType>string</DataType>
<UserHelpText>Your given name (also known as first name).</UserHelpText>
<UserInputType>TextBox</UserInputType>
</ClaimType>
Policy Hierarchies – Parent / Child File Merging
12.
13. Local account
sign-in
Read user by
Object ID from
Azure AD
Local account
sign-up
Relying party
application
Claims
Claims
Claims
Claims bag (session)
Token
Step 1
Step 2
(Skip if objectId
has a value)
Step 3 Step 4
SignUpOrSignInProgressive User Journey
Claims
Assemble Token
Token
Azure AD
OIDC
AAD
AAD
14. LoyaltyNumber Claims Definition
• Id (required)
• Display name (required)
• Data type (required)
• User input type
• Mask
• User help text
• Restriction & Predicate validation
Attribute Value
Id extension_LoyaltyNumber
DisplayName Loyalty-Number
DataType String
UserHelpText Your Loyalty from your membership card
UserInputType TextBox
15.
16. Self-asserted technical profile
• Output Claims with UserInputType
definitions are displayed for data
collection(*)
• The ContentDefinition Metadata
elements specifies the HTML and
data to use on the page
17.
18. • Policies can inherit from “parents” with the BasePolicy element
• Elements with similar ID’s are “merged”
• Locate the same ID, replace matching items
• Otherwise add
• Including “Common” Technical Profile Elements
• Multiple Technical Profiles can inherit from a base Technical Profile via the
IncludeTechnicalProfile element
• Used in AAD Technical Profiles – same common base settings for Read/Write/etc
Inheritance with Azure AD B2C Technical Profiles
21. 1
• Show the sign-in form, sign-up link and password reset
• If user provides credentials on screen, then login to local account
Validate credentials and return the user object ID
2
• If the user signed-in locally, skip this step
• Otherwise, register the user with a new local account
Create the account in the directory and return the user object ID
3
• Read the desired attributes from the user directory for the current
user account
4
• Create a token with the desired claims collected from the current
activity and return the token to the calling app
Azure AD B2C directory services
Progressive account sign-up or sign-in user journey
22. 1
•Show the sign-in form, sign-up link and password reset
•If user provides credentials on screen, then login to local account
Validate credentials and return the user object ID
2
•If the user signed-in locally, skip this step
•Otherwise, register the user with a new local account
Create the account in the directory and return the user object ID
3
•Read the desired attributes from the user directory for the current user account
4
•If the loyalty-number claim exists, skip this step
•If the user is signing up (is a new user), skip this step
Otherwise, prompt the user to enter a Loyalty Number & save to the directory
5
•Create a token with the desired claims collected from the current activity and
return the token to the calling app
Progressive sign-up or sign-in user journey
23. • An Orchestration Step can specify multiple preconditions that
determine if the step is to be run
• 2 Types of Preconditions
• ClaimsExist
• ClaimEquals
• Preconditions specify an Action
• SkipThisOrchestrationStep
• Action is executed
• Based on evaluating the condition
• The value of the ExecuteActionsIf (Boolean) attribute
User Journeys – Preconditions
26. Local account
sign-in
Read user by
Object ID from
Azure AD
Local account
sign-up
Relying party
application
Claims
Claims
Claims
Claims bag (session)
Token
Step 1
Step 2
(Skip if objectId
has a value)
Step 3 Step 4
SignUpOrSignInProgressive User Journey
Claims
Assemble Token
Token
Azure AD
OIDC
AAD
AAD
27. Local account
sign-in
Read user by
Object ID from
Azure AD
Local account
sign-up
Relying party
application
Claims
Claims
Claims
Claims bag (session)
Token
Step 1
Step 2
(Skip if
objectId
has a
value)
Step 3
Step 4
(Skip if
Loyalty
Number
has a
value or
new user)
Step 5
SignUpOrSignInProgressive User Journey
Claims
Assemble Token
Token
Show Profile
Edit and Save
Changes
Claims
Azure AD
OIDC
AAD
AAD
AAD
28. • Claims included as Output Claims
in the RelyingParty section are
included in the token
• Optionally, ClaimType references:
• Can include a DefaultValue
• Can include a PartnerClaimType
Relying Party – Returning Claims
29.
30. Please take a few minutes to complete the feedback survey,
and we'll prepare a few questions to discuss.
https://aka.ms/B2CTheoryPostCallSurvey/
Feedback and Q&A
31. Thank you!
Vinu Gunasekaran
Program Manager, Microsoft
John Garland
VP Cloud Development & Instructor, Wintellect
Azure MVP, MCT, P-CSA
wintellect.com
@dotnetgator
Hinweis der Redaktion
Green = “You are here”
Remaining sessions in blue.
Custom Policies Part 2 will focus on walking through the lab policy and reviewing the details involved in producing a real-world Azure AD B2C Custom Policy
Custom Policies Part 3 will discuss troubleshooting and other helpful techniques for working with Azure AD B2C custom policies
In the previous session, we presented the scenario that we would walk through today. To review, assume that your project has asked you to configure Azure AD B2C to sign up new customers or sign in existing customers. Users will only use local credentials – no 3rd party Identity Providers quite yet. Beyond customer’s email address, first, and last names, you also need to collect a Loyalty Number from your customers (a Loyalty Number is basically one of those grocery store membership points club numbers.)
However, you want to make sure the initial sign-up for your customers is as quick and brief as possible, so you don’t want to initially bother them with the Loyalty Number information. This is known as a Progressive Profile technique – where you initially prompt users for the minimum information, but then gradually ask for more and more information until you’ve completed their profile.
We’ve published the scenario for you at the link below. This writeup includes a walkthrough of a version of the solution that we will be walking through today.
Let’s also review the steps that were discussed in the previous session that you will need to take to get started with setting up an Azure AD B2C tenant to work with custom policies.
First, you need to create an instance of the Azure AD B2C service – this will create a special Azure AD tenant that is set up with the elements it needs for Azure AD B2C. You then need to link that tenant back to a resource in an Azure subscription so the B2C billing can be managed through that Azure subscription.
Next, you will need to create the keys that your custom policies will use to sign and encrypt tokens.
Assuming you’re working with Local Accounts, you will register a pair of applications that allow your policies to use the Azure AD B2C tenant’s OpenID Connect endpoints to sign in users
If you’re working with Custom Claims, you will also need to obtain a couple of values that will be used to work with the underlying Azure AD data store to save and retrieve those claims.
Finally, if your policy works with external identity providers (like Facebook, etc.), you will need to register your Azure AD B2C instance with that identity provider and use the values they give you to configure your policy to work with them.
Don’t worry if this seems like a lot to remember - these steps are all documented in the Getting Started section of the Azure AD B2C Custom Policy documentation.
Show the process for the basic steps; optionally record the relevant values in the table here.
Tenant provisioning and linking
Creating the signing & encryption keys
Creating the IdentityExperienceFramework apps
Obtaining values from the Extensions App
Now that the tenant is configured to be able to work with Custom Policies, the next step is to prepare the policy files.
To get started, you can download or clone the Custom Policy Starter Pack
Next, use the appropriate Starter Pack files to create a workspace with the files you will edit for the policy you are creating
Update those files with your Azure AD B2C tenant name
Update the policy settings based on the values you collected when you configured your tenant
Create the Relying Party element for your policy and the user journey that the relaying party will reference
Strongly recommend you deploy and test your policy at this point, and make sure everything is configured properly
One of the keys to effectively developing custom policies is to move in small increments and test your progress often.
The previous session briefly introduced the concept of inheritance and composition across Custom Policy files.
When policy files inherit from each other, you basically start with the base file, and work your way down the inheritance chain. As you encounter elements, items with the same ID are merged, with the child elements that have the same ID overriding the corresponding parent items.
Here you see an example of Parent/Child merging. The DisplayName in the parent is overridden by the Child definition, resulting in the Merged values shown here.
Policy Setup
Clone the repository
Create the ProgresiveProfile folder
Fix up the policy files
Rename SUSI to ProgressiveProfileSUSI
Update policy ID
Update Settings Values
Verify JWTIssuer Signing/Encryption values
Replace values in Extensions::Local-NonInteractive TP (discuss ID override)
Copy the SUSI UserJourney & rename to SUSIProgresive
Update RP section to use SUSIPorgressive journey
Upload the files
Run/Test
Let’s review our policy’s User Journey so far. Currently our SignUpOrSignInProgressive journey is made up of 4 steps:
The Local Account Sign In is a special hybrid step that shows the combined signup and signin UI. If the user opts to log in, the Technical Profile in this step uses a Validation Technical Profile to call the login-noninteractive OpenIDConnect Profile, which makes an OIDC call to the endpoint provided by your B2C tenant’s Azure AD instance. This call attempts to verify the user’s credentials and returns among other things, an Object ID for the user’s account if they are valid.
The next step checks if an Object ID value exists in the Claims Bag. If it does not, the journey calls a Technical Profile that prompts the user to Sign Up with a Local Account. This profile also uses a Validation Technical Profile – this time one based on the Azure AD protocol, to create a user account in the underlying Azure AD tenant data store. This process will also return an Object ID, this time the Object ID of the created user.
Next, a Technical Profile is called that reads the user details based on their account’s Object ID, whether that was obtained from the Sign in or Sign up step.
Finally, a JWT token is assembled and returned back to the calling application
The next step to extend the policy to meet the scenario is to add a custom claim to represent the user’s Loyalty Number. Since Azure AD B2C doesn’t have a pre-existing claim that meets this need, you will need to extend the schema by defining a custom claim.
This claim will have an ID of “extension_LoyaltyNumber”, a display name of “Loyalty-Number”, a data type of String, some text to help the user know what to enter, and it will be collected with a TextBox control.
Add the extension_LoyaltyNumber claim declaration
With the claim defined, it is time to assemble or update the user interface that will be used to collect it. This involves defining and configuring a Self-Asserted Technical Profile. Recall that any Output Claims in a Self-Asserted TP that include a UserInputType declaration are used for data collection.
In addition to the data that is to be collected, Self-Asserted Technical Profiles also include a ContentDefinition Metadata element that determines the HTML that provides the look and feel of the user interface.
(*)Note – there is another way to define claims for data collection in a Self-Asserted TP, through the use of the DisplayClaims element. This is an either-or proposition, however. Once you use DisplayClaims, any OutputClaims in the current profile are ignored when the UI is assembled, and they are only used for determining the claims put back into the Claims Bag by the TP.
https://github.com/Azure-Samples/Azure-AD-B2C-page-templates/tree/master/
Override/update the SelfAsserted-ProfileUpdate SATP to include the loyalty number output claim
In addition to inheritance between policy files and elements with matching ID’s, there is another inheritance strategy that we can take advantage of with Technical Profiles Azure AD B2C Custom Policies.
Technical Profiles can use the IncludeTechnicalProfile element to configure an inheritance chain between different Technical Profiles. This allows several different Technical Profiles to share the elements defined in a common base profile. This is most commonly used in the Azure AD Technical Profile declarations.
Here you see an example of sharing Technical Profile definitions through the IncludeTechnicalProfile declaration. The four Technical Profiles on the bottom all reference the common Technical Profile up top and receive all of its attributes, although they may have their own specific functionality defined in their content.
Override the AAD-Common TP to include the Metadata elements required to work with Custom Attributes
Override the AAD-WriteProfileUsingObjectId and AAD-UserReadUsingObjectId TP’s to add the Loyalty Number claim
Review the points/steps that make up the “regular” Sign-up/Sign-In User Journey
Discuss the change that is to be made to the User Journey:
Add a new step that checks the preconditions that must be met, then optionally prompt the user to collect their Loyalty Number and save it back to the directory
Steps can be optionally executed in a User Journey through the use of Preconditions. An Orchestration Step can declare one or more Preconditions that are evaluated when it is the Orchestration Step’s turn to run. If a Precondition is matched, its Action gets run – right now the only action that can be run is “Skip this Step”.
There are two types of Preconditions you can declare – ClaimsExist and ClaimEquals. ClaimsExist checks to see if a given Claim exists in the ClaimsBag. ClaimEquals checks a claim against a provided value.
Remember, though – the first precondition to match executes the action – there is no current support for Boolean matches like And or Or – but you can declare additional Claims and Claims Transformations that you can use to do those calculations in an earlier step, and then evaluate that resulting value. You can invert the logic of these checks by adding an ExecuteActionsIf attribute.
In this example, the Technical Profile with an ID of “SampleUserInputCollector” is SKIPPED if the Claims Bag contains an Object ID claim. The Precondition checks for the ObjectID with a ClaimsExist check, and if it extists (because “ExecuteActionIf” is set to True), it performs the SkipThisStep action.
Add the new Orchestration Step with Preconditions
If you recall, this is the UserJourney that you initially started with.
Notice now that the new 4th step optionally shows the Profile Editing Self-Asserted Technical Profile. That TP in turn will use a Validation Technical Profile to write the updated user information – including the new Loyalty Number claim value – back to the underlying Azure AD data store.
The final change to discuss is to include the new Loyalty Number claim in the resulting JWT token. To include a claim in the token, you add the claim in the OutputClaims section of the Relying Party element.
There are a couple of interesting things worth mentioning about ClaimType references, and this applies not only to the Relying Party section, but anywhere that a ClaimType reference is included.
First, you can use the DefaultValue attribute to include a value to use for a Claim if it does not already exist in the claims. So perhaps we may want to include the value “Unset” in our token if the Loyalty Number claim has not been set (otherwise it will simply be omitted.)
Second, you can use the PartnerClaimType attribute to give the claim an alternate name when it is exchanged with a Partner – for example, If your application is dependent on the claim having the specific name “loyaltyNumber” and including the “extension_” prefix would cause a problem in your application code, you can specify this different exchange name. This is particularly useful for HTTP requests, where the API may already be defined and may not directly align with the claim names you’re using in your policy – you can just tell the REST Technical Profile the names to use when it is sending or receiving the claims.
Add the Loyalty Number output claim
OPTIONAL: Add a PartnerClaimType and/or a Default Value