what is maximum character length of email in Azure Custom ADB2C policy
this is my claim type
<ClaimType Id="signInName">
<DisplayName>Email Address</DisplayName>
<DataType>string</DataType>
<UserHelpText />
<UserInputType>TextBox</UserInputType>
<Restriction>
<Pattern RegularExpression="^[a-zA-Z0-9.+!#$%&'^_`{}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" HelpText="Please enter a valid email address." />
</Restriction>
</ClaimType>
As long as it's a valid email it should work (ie charachters#domain.com).
B2C doesn't have limitation on valid email address.
Related
I am using starter pack of custom polices with the SocialAndLocalAccounts package to sign in with an Azure Active Directory account.
I customized the flows with custom attributes and it works well for me.
I need to receive the email used for the login (username = email).
In RelyingParty I have this OutputClaims
<OutputClaim ClaimTypeReferenceId = "signInName" />
<OutputClaim ClaimTypeReferenceId = "signInNames.emailAddress" PartnerClaimType = "email" />
<OutputClaim ClaimTypeReferenceId = "otherMails" />
When a user signs-in with a local b2c account, I get the email
in "signInName" and "email" claims,
but when a user signs-in with an AzureAd account , the claims are empty.
How can I get the email?
How must I write the custom policies (TrustFrameworkBase and TFExtensions) ?
Can you help me ?
When the Azure AD identity is signed-in with for the first time, you must map from the upn claim that is issued by Azure AD to the email claim that is used by Azure AD B2C, so that this email claim can be:
Written as the otherMails property in the user object to the Azure AD B2C directory.
Issued by Azure AD B2C in the ID token to the client application.
To map from the upn claim that is issued by Azure AD to the email claim that is used by Azure AD B2C, add a new <OutputClaim /> to the Azure AD authentication technical profile:
<ClaimsProvider>
<Domain>commonaad</Domain>
<DisplayName>Common AAD</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="Common-AAD">
<DisplayName>Multi-Tenant AAD</DisplayName>
<Protocol Name="OpenIdConnect" />
...
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="upn" />
</OutputClaims>
...
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
The AAD-UserWriteUsingAlternativeSecurityId technical profile converts the email claim to the otherMails claim by invoking the CreateOtherMailsFromEmail claims transformation and then saves the otherMails claim to the user object.
To issue the email claim in the ID token to your client application, add a new <OutputClaim /> to the relying party technical profile:
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
...
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="otherMails" PartnerClaimType="emails" />
</OutputClaims>
...
</TechnicalProfile>
</RelyingParty>
I am trying to collect user details using LocalAccountSignUpWithLogonName custom policy.I have added <OutputClaim ClaimTypeReferenceId="email" />
to LocalAccountSignUpWithLogonName as outputclaim. I want to make the email field optional, but if user enter the email I want to enable the restrictions.Below is my email claim
<ClaimType Id="email">
<DisplayName>Your Email Address</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OpenIdConnect" PartnerClaimType="email" />
</DefaultPartnerClaimTypes>
<UserHelpText>Email address that can be used to contact you.</UserHelpText>
<UserInputType>TextBox</UserInputType>
<Restriction>
<Pattern RegularExpression="^[a-zA-Z0-9.+!#$%&'^_{}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" HelpText="Please enter a valid email address." />
</Restriction>
But when I add the pattern restriction to claim, its making the field mandatory.
I achieved it by changing the regular expression from RegularExpression="^[a-zA-Z0-9.+!#$%&'^_{}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" to RegularExpression="^$|^[a-zA-Z0-9.+!#$%&'^_{}~-]+#[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$" `.
I had to prefix the expression with ^$| which accept blank/empty or the actual email.
I've been using the built-in SignUpOrSignIn policy for a while, but I'm now moving to a custom policy.
When I set up the built-in policy, I was able to choose from a list of built-in application claims (like displayName and jobTitle), and select which ones I wanted to be returned in the token when the user signed in.
Now I'm setting up the custom policy I want to do the same thing, but I can't get it to work.
So far, in TrustFrameworkBase I have added a ClaimType of jobTitle:
<ClaimType Id="jobTitle">
<DisplayName>Job Title</DisplayName>
<DataType>string</DataType>
<UserHelpText>Job title.</UserHelpText>
</ClaimType>
I've added the following OutputClaim to the TechnicalProfile with ID login-NonInteractive:
<OutputClaim ClaimTypeReferenceId="jobTitle" PartnerClaimType="jobTitle" />
And I've added the following OutputClaim to the TechnicalProfile with ID SelfAsserted-LocalAccountSignin-Email:
<OutputClaim ClaimTypeReferenceId="jobTitle" />
But the jobTitle claim doesn't come through with the others in the token. I've done the same for given_name and that does work. If I change the first OutputClaim to:
<OutputClaim ClaimTypeReferenceId="jobTitle" PartnerClaimType="given_name" />
then a jobTitle claim does come through, but with the value of the given_name claim. This implies I'm just using the wrong PartnerClaimType but there doesn't seem to be a list of them anywhere.
How can I get the built-in job title attribute to be returned as a claim in the token when the user signs in using their local B2C account?
If you only want to read the jobTitle claim (or other claims) for the user and then issue it (or them) in the token, then you must:
1) Declare the jobTitle claim:
<ClaimType Id="jobTitle">
<DisplayName>Job Title</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="job_title" />
<Protocol Name="OpenIdConnect" PartnerClaimType="job_title" />
</DefaultPartnerClaimTypes>
</ClaimType>
2) Add the jobTitle claim as an output claim to the AAD-UserReadUsingObjectId technical profile:
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
...
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="jobTitle" />
</OutputClaims>
...
</TechnicalProfile>
3) Add the jobTitle claim as an output claim to the relying party technical profile:
<RelyingParty>
...
<TechnicalProfile Id="PolicyProfile">
...
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="jobTitle" />
</OutputClaims>
...
</TechnicalProfile>
</RelyingParty>
When I try to execute my sign-up policy I'm receiving:
Why?
I was trying to display the field but I hadn't defined the <UserInputType> node.
<ClaimType Id="extension_HelloWorld">
<DisplayName>Hello World</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="HelloWorld" />
<Protocol Name="OpenIdConnect" PartnerClaimType="HelloWorld" />
</DefaultPartnerClaimTypes>
<!-- I had the following line commented out -->
<!--<UserInputType>Readonly</UserInputType>-->
</ClaimType>
I have 2 claims that I want to store in the Directory for my application to use. These are not available for the user to edit however is available for the application to read from the Token.
The BuiltIn policies are able to retrieve the claims however, I have not had any success with retrieving these claims using Custom Policies.
Reading through Next Steps of the article “Creating and using custom attributes in a custom profile edit policy” the claims will need to be added to the RP and TechnicalProfile to read from Directory. I accordingly updated the RP and as well the TP's that read from Directory such as
<TechnicalProfile Id="AAD-UserReadUsingAlternativeSecurityId">
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email">
<TechnicalProfile Id="AAD-UserReadUsingEmailAddress">
Unable to figure out what might be missing to retreive the 2 extension claims.
Assuming you are reading the custom claims in the user journeys and writing them via the Azure AD Graph API, then you must:
1: Add the custom claims as <ClaimType />s to the base policy.
<ClaimType Id="extension_UserAttribute1">
<DisplayName>User Attribute 1</DisplayName>
<DataType>string</DataType>
</ClaimType>
<ClaimType Id="extension_UserAttribute2">
<DisplayName>User Attribute 2</DisplayName>
<DataType>string</DataType>
</ClaimType>
2: Add the application and object identifiers for the extensions app to the "AAD-Common" technical profile which is required to read the custom claims from the Azure AD B2C directory.
<TechnicalProfile Id="AAD-Common">
<DisplayName>Azure Active Directory</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.AzureActiveDirectoryProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ApplicationObjectId">Insert the object identifier for the b2c-extensions-app application here</Item>
<Item Key="ClientId">Insert the application identifier for the b2c-extensions-app application here</Item>
</Metadata>
<CryptographicKeys>
<Key Id="issuer_secret" StorageReferenceId="TokenSigningKeyContainer" />
</CryptographicKeys>
...
</TechnicalProfile>
Note: If you are wanting to read the custom claims in both built-in policies and custom policies, then you must use the application and object identifiers for the built-in b2c-extensions-app application rather than a custom extensions app as suggested by the Azure Active Directory B2C: Creating and using custom attributes in a custom profile edit policy tutorial.
3: Add the custom claims as <OutputClaim />s to the following technical profiles:
"AAD-UserReadUsingObjectId" for local account sign-in and profile editing
"AAD-UserReadUsingAlternativeSecurityId" for a social account sign-in and profile editing
"LocalAccountDiscoveryUsingEmailAddress" and "AAD-UserReadUsingEmailAddress" for a local account password reset
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="extension_UserAttribute1" />
<OutputClaim ClaimTypeReferenceId="extension_UserAttribute2" />
</OutputClaims>
4: Issue the custom claims as <OutputClaim />s in any relying party policies.
Thanks #ChrisPadget. For anybody still struggling. Make sure that the UserJourney Step that reads data from AD is actually available in your User Journey. In my case, I had to add:
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>