Created
February 26, 2020 21:48
-
-
Save ahelland/e2fce4ca81067a9ed09bbb8f7380c3fd to your computer and use it in GitHub Desktop.
Azure AD B2C Custom Policy for handling SignUp with id_token_hint
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
<TrustFrameworkPolicy | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:xsd="http://www.w3.org/2001/XMLSchema" | |
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" | |
PolicySchemaVersion="0.3.0.0" | |
TenantId="yourtenant.onmicrosoft.com" | |
PolicyId="B2C_1A_signup_invitation" | |
PublicPolicyUri="http://yourtenant.onmicrosoft.com/B2C_1A_signup_invitation"> | |
<BasePolicy> | |
<TenantId>yourtenant.onmicrosoft.com</TenantId> | |
<PolicyId>B2C_1A_TrustFrameworkExtensions_Dev</PolicyId> | |
</BasePolicy> | |
<BuildingBlocks> | |
<ClaimsSchema> | |
<!-- Read-only email address to present to the user--> | |
<ClaimType Id="ReadOnlyEmail"> | |
<DisplayName>Verified Email Address</DisplayName> | |
<DataType>string</DataType> | |
<UserInputType>Readonly</UserInputType> | |
</ClaimType> | |
<!-- Stores the error message for unsolicited request (a request without id_token_hint) and user not found--> | |
<ClaimType Id="errorMessage"> | |
<DisplayName>Error</DisplayName> | |
<DataType>string</DataType> | |
<UserHelpText>Add help text here</UserHelpText> | |
<UserInputType>Paragraph</UserInputType> | |
</ClaimType> | |
</ClaimsSchema> | |
<ClaimsTransformations> | |
<!-- Initiates the errorMessage claims type with the error message--> | |
<ClaimsTransformation Id="CreateUnsolicitedErrorMessage" TransformationMethod="CreateStringClaim"> | |
<InputParameters> | |
<InputParameter Id="value" DataType="string" Value="You cannot sign-up without invitation" /> | |
</InputParameters> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="errorMessage" TransformationClaimType="createdClaim" /> | |
</OutputClaims> | |
</ClaimsTransformation> | |
<!-- Copy the email to ReadOnlyEamil claim type--> | |
<ClaimsTransformation Id="CopyEmailAddress" TransformationMethod="FormatStringClaim"> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="email" TransformationClaimType="inputClaim" /> | |
</InputClaims> | |
<InputParameters> | |
<InputParameter Id="stringFormat" DataType="string" Value="{0}" /> | |
</InputParameters> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="ReadOnlyEmail" TransformationClaimType="outputClaim" /> | |
</OutputClaims> | |
</ClaimsTransformation> | |
</ClaimsTransformations> | |
</BuildingBlocks> | |
<ClaimsProviders> | |
<ClaimsProvider> | |
<DisplayName>Local Account</DisplayName> | |
<TechnicalProfiles> | |
<!-- Sign-up self-asserted technical profile--> | |
<TechnicalProfile Id="LocalAccountSignUpWithReadOnlyEmail"> | |
<DisplayName>Email signup</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> | |
<Metadata> | |
<Item Key="IpAddressClaimReferenceId">IpAddress</Item> | |
<Item Key="ContentDefinitionReferenceId">api.localaccountsignup</Item> | |
<Item Key="language.button_continue">Create</Item> | |
<!-- Remove sign-up email verification --> | |
<Item Key="EnforceEmailVerification">False</Item> | |
</Metadata> | |
<InputClaimsTransformations> | |
<!-- Copy the email to ReadOnlyEamil claim type--> | |
<InputClaimsTransformation ReferenceId="CopyEmailAddress" /> | |
</InputClaimsTransformations> | |
<InputClaims> | |
<!-- Set input the ReadOnlyEmail claim type to prefilled the email address--> | |
<InputClaim ClaimTypeReferenceId="ReadOnlyEmail" /> | |
<InputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="displayName" /> | |
<InputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="givenName"/> | |
<InputClaim ClaimTypeReferenceId="surname" PartnerClaimType="surname" /> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="objectId" /> | |
<!-- Display the ReadOnlyEmail claim type (instead of email claim type)--> | |
<OutputClaim ClaimTypeReferenceId="ReadOnlyEmail" Required="true" /> | |
<OutputClaim ClaimTypeReferenceId="newPassword" Required="true" /> | |
<OutputClaim ClaimTypeReferenceId="reenterPassword" Required="true" /> | |
<OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="true" /> | |
<OutputClaim ClaimTypeReferenceId="authenticationSource" /> | |
<OutputClaim ClaimTypeReferenceId="newUser" /> | |
<!-- Pre-filled from token_hint --> | |
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="displayName" /> | |
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="givenName" /> | |
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="surname" /> | |
</OutputClaims> | |
<ValidationTechnicalProfiles> | |
<ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" /> | |
</ValidationTechnicalProfiles> | |
<!-- Disable session management for sign-up page --> | |
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" /> | |
</TechnicalProfile> | |
</TechnicalProfiles> | |
</ClaimsProvider> | |
<ClaimsProvider> | |
<DisplayName>Self Asserted</DisplayName> | |
<TechnicalProfiles> | |
<!-- Show error message--> | |
<TechnicalProfile Id="SelfAsserted-Unsolicited"> | |
<DisplayName>Unsolicited error message</DisplayName> | |
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> | |
<Metadata> | |
<Item Key="ContentDefinitionReferenceId">api.selfasserted</Item> | |
<!-- Remove the continue button--> | |
<Item Key="setting.showContinueButton">false</Item> | |
</Metadata> | |
<InputClaimsTransformations> | |
<InputClaimsTransformation ReferenceId="CreateUnsolicitedErrorMessage" /> | |
</InputClaimsTransformations> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="errorMessage"/> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="errorMessage"/> | |
</OutputClaims> | |
</TechnicalProfile> | |
</TechnicalProfiles> | |
</ClaimsProvider> | |
<!--Sample: This technical profile specifies how B2C should validate your token, and what claims you want B2C to extract from the token. | |
The METADATA value in the TechnicalProfile meta-data is required. | |
The “IdTokenAudience” and “issuer” arguments are optional (see later section)--> | |
<ClaimsProvider> | |
<DisplayName>My ID Token Hint ClaimsProvider</DisplayName> | |
<TechnicalProfiles> | |
<TechnicalProfile Id="IdTokenHint_ExtractClaims"> | |
<DisplayName> My ID Token Hint TechnicalProfile</DisplayName> | |
<Protocol Name="None" /> | |
<Metadata> | |
<!--Sample action required: replace with your endpoint location --> | |
<Item Key="METADATA">https://yourtenant.b2clogin.com/yourtenant.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1A_OIDC</Item> | |
<!-- <Item Key="IdTokenAudience">your_optional_audience_override</Item> --> | |
<!-- <Item Key="issuer">your_optional_token_issuer_override</Item> --> | |
</Metadata> | |
<OutputClaims> | |
<!-- Read the email cliam from the id_token_hint--> | |
<OutputClaim ClaimTypeReferenceId="email" /> | |
</OutputClaims> | |
</TechnicalProfile> | |
</TechnicalProfiles> | |
</ClaimsProvider> | |
</ClaimsProviders> | |
<UserJourneys> | |
<UserJourney Id="SignUpInvitation"> | |
<OrchestrationSteps> | |
<!-- Read the input claims from the id_token_hint--> | |
<OrchestrationStep Order="1" Type="GetClaims" CpimIssuerTechnicalProfileReferenceId="IdTokenHint_ExtractClaims" /> | |
<!-- Check if user tries to run the policy without invitation --> | |
<OrchestrationStep Order="2" Type="ClaimsExchange"> | |
<Preconditions> | |
<Precondition Type="ClaimsExist" ExecuteActionsIf="true"> | |
<Value>email</Value> | |
<Action>SkipThisOrchestrationStep</Action> | |
</Precondition> | |
</Preconditions> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="SelfAsserted-Unsolicited" TechnicalProfileReferenceId="SelfAsserted-Unsolicited"/> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<!-- Self-asserted sign-up page --> | |
<OrchestrationStep Order="3" Type="ClaimsExchange"> | |
<ClaimsExchanges> | |
<ClaimsExchange Id="LocalAccountSignUpWithReadOnlyEmail" TechnicalProfileReferenceId="LocalAccountSignUpWithReadOnlyEmail"/> | |
</ClaimsExchanges> | |
</OrchestrationStep> | |
<!-- Issue an access token--> | |
<OrchestrationStep Order="4" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer"/> | |
</OrchestrationSteps> | |
<ClientDefinition ReferenceId="DefaultWeb"/> | |
</UserJourney> | |
</UserJourneys> | |
<RelyingParty> | |
<DefaultUserJourney ReferenceId="SignUpInvitation" /> | |
<UserJourneyBehaviors> | |
</UserJourneyBehaviors> | |
<TechnicalProfile Id="PolicyProfile"> | |
<DisplayName>PolicyProfile</DisplayName> | |
<Protocol Name="OpenIdConnect" /> | |
<InputClaims> | |
<InputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" /> | |
<InputClaim ClaimTypeReferenceId="surname" PartnerClaimType="surname" /> | |
<InputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="displayName"/> | |
<InputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="givenName" /> | |
</InputClaims> | |
<OutputClaims> | |
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="displayName" /> | |
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="givenName" /> | |
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="family_name" /> | |
<OutputClaim ClaimTypeReferenceId="email" /> | |
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/> | |
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" /> | |
</OutputClaims> | |
<SubjectNamingInfo ClaimType="sub" /> | |
</TechnicalProfile> | |
</RelyingParty> | |
</TrustFrameworkPolicy> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment