I am getting this error while uploading signup policy.
Validation failed: 1 validation error(s) found in policy
"B2C_1A_SIGNUP_WEB_SP" of tenant
"titanidaasdevb2c.onmicrosoft.com".DisableStrongPassword is required
in Technical Profile 'AAD-UserWriteUsingLogonEmail' of policy
'B2C_1A_SignUp_Web_SP' for custom password complexity or legacy
password restriction with weak custom regular expression. Add
"DisablePasswordExpiration, DisableStrongPassword" into PersistedClaim
"passwordPolicies"
Please guide me on this.
Because you are implementing a custom complexity, you must disable the built-in complexity, by setting the passwordPolicies claim to DisableStrongPassword.
This claim value can be set in either the relying party technical profile (i.e. if the custom complexity is applicable for a specific flow):
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn"/>
<TechnicalProfile Id="PolicyProfile">
<InputClaims>
<InputClaim ClaimTypeReferenceId="passwordPolicies" DefaultValue="DisablePasswordExpiration, DisableStrongPassword"/>
</InputClaims>
</TechnicalProfile>
</RelyingParty>
Or the AAD-UserWriteUsingLogonEmail technical profile (i.e. if the custom complexity is applicable for all flows):
<TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
<PersistedClaims>
<PersistedClaim ClaimTypeReferenceId="passwordPolicies" DefaultValue="DisablePasswordExpiration, DisableStrongPassword" />
</PersistedClaims>
</TechnicalProfile>
Related
I have integrated Azure authentication in my project, it working good so far but, when I checked my azure ad users the username is showing unknown, I search every where but I can't found any suitable result that tells me what is the reason and problem, Azure signin_signup policy working good, when I was testing the policy first I signup and then I sign-in, when login is successfully I decode the token of the azure token and I found both name but not azure ad user name is unknown.
• Since, you are using Azure AD B2C custom policies regarding ‘Signup and Signin’, which are working fine but when you are trying to decode the token received for information in it, you are not getting information on the ‘username’ of the signed in user, it is because of the ‘Validation Technical Profile’ section being executed before the ‘OutputClaimsTransformation’ section. Thus, when signing up with an Azure AD local user account, the ‘LocalAccountSignUpWithLogonEmail’ technical profile is used which includes ‘AAD-UserWriteUsingLogonEmail’ technical profile as the validation technical profile. As a result, if you check the ‘AAD-UserWriteUsingLogonEmail’ technical profile in your signin-signup policy, you can see that in your ‘PersistedClaim ClaimTypeReferenceId="displayName" DefaultValue="unknown" />’ is stated. As a result, since the validation technical profile runs before ‘OutputClaimTransformation’, you are getting the ‘DefaultValue’ of ‘unknown’.
Thus, the claims transformation profile should be as below in your signup-signin policy: -
<ClaimsTransformation Id="CreateDisplayNameFromFirstNameAndLastName" TransformationMethod="FormatStringMultipleClaims">
<InputClaims>
<InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="inputClaim1" />
<InputClaim ClaimTypeReferenceId="surName" TransformationClaimType="inputClaim2" />
</InputClaims>
<InputParameters>
<InputParameter Id="stringFormat" DataType="string" Value="{0} {1}" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
• Accordingly, ensure that the ‘Technical profile’ is also updated in your ‘LocalAccountSigninSignup’ custom policy as shown below and add ‘Validate-DisplayName’ technical profile as validation technical profile under ‘LocalAccountSignUpWithLogonEmail’ technical profile as mentioned below (in same order): -
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="Validate-DisplayName" />
<ValidationTechnicalProfile ReferenceId="AAD-UserWriteUsingLogonEmail" />
</ValidationTechnicalProfiles>
Thus, this would help you to resolve this issue of getting ‘unknown’ in the username. For more information, kindly refer the below link: -
https://learn.microsoft.com/en-us/answers/questions/713037/display-the-name-of-user-in-ad-b2c-instead-of-unkn.html
I am trying to set up a custom B2C policy according to sample available at: https://github.com/azure-ad-b2c/samples/blob/master/policies/force-password-reset-after-90-days/policy/TrustFrameworkExtensions.xml
The problem I face is that on every sign in pass change is prompted. I narrowed down the issue to
InputClaim isPasswordResetOnPresent always returned as false from where output claim "skipPasswordReset" is also FALSE every time
and i believe this is my failing piece
<!--Sample: Check if extension_passwordResetOn is existed in user account. -->
<ClaimsTransformation Id="CheckIfPasswordResetOnPresent" TransformationMethod="DoesClaimExist">
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_passwordResetOn" TransformationClaimType="inputClaim" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="isPasswordResetOnPresent" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
This is evaluated in my Azure AD B2C trace as:
InputClaim extension_passwordResetOn undefined
I also followed all recommendations as per this similar question
Azure B2C: Where to Create DateTime Extension Attribute to be used in Custom Policy- Portal or Custom Policy or Both?
But that extension_passwordResetOn is always determined as undefined in claims transformation
In the same time I can see this extension get current date/time correctly assigned in this technical profile
<TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
<InputClaimsTransformations>
<!--Sample: Get current date and time -->
<InputClaimsTransformation ReferenceId="SetPasswordResetOn" />
</InputClaimsTransformations>
<PersistedClaims>
<!--Sample: On sign-up, set the 'password reset on' extension attribute with the current date and time -->
<PersistedClaim ClaimTypeReferenceId="extension_passwordResetOn" />
</PersistedClaims>
</TechnicalProfile>
I am using Azure AD B2C and custom policies to manage users and give sign in experience. I noticed that there is an inbuilt(not a custom extension) attribute name companyName which i am updating with user's company information. I am able to update this filed value via graph API and retrieve it respectively. Once this value is updated i am trying to include this in claims and send to client application however i am running into an issue. I have made sure to include a claim in TrustFrameworkBase policy like below
<ClaimType Id="companyName">
<DisplayName>companyName</DisplayName>
<DataType>string</DataType>
</ClaimType>
Also i have updated AAD-UserReadUsingObjectId techincal profile which is responsible for making a graph call (after successful authentication) and get all user attributes. here is definition for AAD-UserReadUsingObjectId technical profile
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
<Metadata>
<Item Key="Operation">Read</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" Required="true" />
</InputClaims>
<OutputClaims>
<!-- Optional claims -->
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" />
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="mobile" />
<OutputClaim ClaimTypeReferenceId="country" />
<OutputClaim ClaimTypeReferenceId="postalCode" />
<OutputClaim ClaimTypeReferenceId="state" />
<OutputClaim ClaimTypeReferenceId="company" />
<OutputClaim ClaimTypeReferenceId="companyName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="objectId" />
<!--Adding custom attribute start-->
<OutputClaim ClaimTypeReferenceId="otherMails" />
<OutputClaim ClaimTypeReferenceId="extension_UserGuid" />
<OutputClaim ClaimTypeReferenceId="extension_StatusFlag" />
<OutputClaim ClaimTypeReferenceId="extension_EZUserName" />
<OutputClaim ClaimTypeReferenceId="CurrentTime" />
<!--Adding custom attribute end-->
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="GetSystemDateTime" />
</OutputClaimsTransformations>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
and finally i have included this companyName claim in user journey output claims.
Even after doing all this i noticed that companyName claim is not inside the token returned by azure AD B2C.
To trouble shoot further i enabled application insight for my policies and i observed a weird behavior.
When Azure AD B2C makes a graph call while executing AAD-UserReadUsingObjectId technical profile it forms a query something like below
https://graph.windows.net/f17d6207-7c3a-4d29-b802-ad5429b2a8d8/users/77669822-8034-4666-9800-8b614c0ccbfc?api-version=1.6-integrationOnly
and output of this graph api call does not include companyName attribute at all however when i make graph api call with similar query using my application id and secrete i do see companyName in the response. The only difference in the query which Azure AD B2C call vs i am calling the last part in api url. Azure AD B2C has -integrationOnly at the end where as i dont. I am not sure why graph API call response is differnet when Azure AD B2C makes it vs when i make it.
I can solve this issue by simply adding a new custom extension field and using that instead of companyName but my point is why i should create a custom attribute when one is provided out of the box and more importantly it will require me to fix about 1 million existing users.
has anyone come across this type of issue. Any help would be great!
Thanks in Advance!
CompanyName is an O365 built in attribute. B2C uses integration-only api version in the backend for its own calls as you’ve seen. The only solution is to use the extension attribute. A script to PATCH the users can fix 1million users in around 12hrs.
When using custom policy, stick to your own custom attributes, there is no real advantage trying to use default attribute names, only sometimes you find disadvantages. Custom policy only needs you to declare the attribute name as extension_ and it works just like any built in attribute.
I am using starter pack of custom polices with SocialAndLocalAccounts pack.
It is working fine for me.
But I am facing one issue.I need to get email as claim after successfully login.
I am getting email as claim, once user has been been signed-up and redirects back immediately to application.
but I am not getting it when a user simply signs-in.
How can I get that?
where do I need to write an Output Claim to get the value of email in claim?
Kindly help me.
Thanks
For Chris Padgett's answer, you can add other emails (Alternate email) into the claim.
If you just want to add email claim from the SignIn name into the token, you can just take following steps:
Open your SignUporSignIn.xml file
Replace <OutputClaim ClaimTypeReferenceId="email" /> with <OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email" />
Save this SignUporSignIn.xml file and upload it to Azure AD B2C to overwrite the policy.
Run the SignUporSignIn policy to test it.
Here is my test result, you can see the email claim in the token:
Hope this helps.
Following describes how you can save, load, and then issue the otherMails claim as emails from the sign-up/sign-in and password reset policies.
When writing a local account: You must create the otherMails claim from the email claim using the CreateOtherMailsFromEmail claims transformation and then persist the otherMails claim in the AAD-UserWriteUsingLogonEmail technical profile:
<TechnicalProfile Id="AAD-UserWriteUsingLogonEmail">
...
<IncludeInSso>false</IncludeInSso>
<InputClaimsTransformations>
<InputClaimsTransformation ReferenceId="CreateOtherMailsFromEmail" />
</InputClaimsTransformations>
<InputClaims>
...
</InputClaims>
<PersistedClaims>
...
<PersistedClaim ClaimTypeReferenceId="otherMails" />
</PersistedClaims>
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="otherMails" />
</OutputClaims>
...
</TechnicalProfile>
You must then pass the otherMails claim out from the LocalAccountSignUpWithLogonEmail technical profile that is invoked to register a local account:
<TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
...
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="otherMails" />
</OutputClaims>
</TechnicalProfile>
When writing a social account: The otherMails claim is already created from the email claim and then persisted in the AAD-UserWriteUsingAlternativeSecurityId technical profile.
You must then pass the otherMails claim out from the SelfAsserted-Social technical profile that is invoked to register a social account:
<TechnicalProfile Id="SelfAsserted-Social">
...
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="otherMails" />
</OutputClaims>
</TechnicalProfile>
When reading a local or social account: The otherMails claim is already read in the AAD-UserReadUsingObjectId, AAD-UserReadUsingEmailAddress, and AAD-UserReadUsingAlternativeSecurityId technical profiles.
You must then pass the otherMails claim out from the LocalAccountDiscoveryUsingEmailAddress technical profile that is invoked to recover a local password:
<TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
...
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="otherMails" />
</OutputClaims>
</TechnicalProfile>
To issue the otherMails claim as emails from the sign-up/sign-in and password reset policies: You must add the otherMails claim as <OutputClaim /> to the relying party policies:
<RelyingParty>
...
<TechnicalProfile Id="PolicyProfile">
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="otherMails" PartnerClaimType="emails" />
</OutputClaims>
</TechnicalProfile>
</RelyingParty>
Another option that is working for me was to extend AAD-UserReadUsingObjectId so that it copies the signInNames.emailAddress claim into email. That brought sign-in into alignment with our other journeys/sub-journeys for integrated sign-up, password reset, and social log-in -- which each populate email during first log-in/sign-up.
All I needed to do was add this to TrustFrameworkExtension.xml (under <ClaimsProviders>):
<ClaimsProvider>
<DisplayName>Azure Active Directory</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
<OutputClaims>
<OutputClaim
ClaimTypeReferenceId="email"
PartnerClaimType="signInNames.emailAddress"
/>
</OutputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
I was curious if it was possible to read query parameters when requesting an OAuth2 token through Azure?
Essentially, when making a test call with a policy that I created, I would like to have an additional query parameters read from the call and the orchestration (user journey) steps should read these values and inject that value into a custom claim (for the JWT or ID token).
I know from the follow links that it may* be possible with Azure B2C service? But I can't find any good concrete examples.
Sign-up policy - Set user attributes through code
Add Custom Attribute Not Used in Sign-Up nor Edit Policy
How can I return the PolicyId Claim after executing my Custom SignUpSignIn policy?
How do i include email in the redirect to AZURE AD B2C
I then proceeded in trying a bunch of configurations out but there are so many options to choose from, I don't know which to choose. In addition, I haven't been able to find any Azure docs that describe the options used when configuring these policies. In any case, here is what I have.
I downloaded the TrustFrameworkBase.xml and TrustFrameworkExtensions.xml from here. I got this Github link from this Azure doc, which I also followed the steps on setting up policy keys and added an app registration with delegated permissions. For my relying party configuration, I simply made a custom policy through the Azure B2C portal and downloaded it as a starting point to explore what it looks like in a basic form.
Here is my custom claim added to the base policy within the ClaimsSchema tag. extension_Test is the claim where I want to inject the value from a query param:
<ClaimType Id="extension_Test">
<DisplayName>Test value</DisplayName>
<DataType>string</DataType>
<DefaultPartnerClaimTypes>
<Protocol Name="OAuth2" PartnerClaimType="extension_Test" />
<Protocol Name="OpenIdConnect" PartnerClaimType="extension_Test" />
</DefaultPartnerClaimTypes>
<UserInputType>Readonly</UserInputType>
</ClaimType>
</ClaimsSchema>
In the same base policy, here's the userjourney that I added for SignIn:
<UserJourney Id="SignIn">
<OrchestrationSteps>
<OrchestrationSteps>
<!-- The following orchestration step is always executed. -->
<OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselection.signupsignin">
<ClaimsProviderSelections>
<ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountRegistrationExchange" />
</ClaimsProviderSelections>
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="LocalAccountRegistrationExchange" TechnicalProfileReferenceId="LocalAccount-Registration-VerifiedEmail" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
</UserJourney>
Here's my relying config XML:
<RelyingParty>
<DefaultUserJourney ReferenceId="SignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_Test" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="extension_Test" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>
I think uploaded the base, extensions and RP policies XML files in that order. The GET request that I'm sending looking like this (got from the "Run now" button for the custom policy):
https://login.microsoftonline.com/<TENANT>/oauth2/v2.0/authorize?p=B2C_1A_test&client_id=<TENANTID>&nonce=defaultNonce&redirect_uri=http%3A%2F%2Flocalhost%2Fredirect&scope=openid&response_type=id_token&prompt=login&extension_Test=aaa
Any help would be greatly appreciated, thanks! Or Azure documents that explain more options within these config files - as in what does CpimIssuerTechnicalProfileReferenceId="JwtIssuer" mean? Or AzureFunction-WrapWebHook mean?
You are close.
An end-to-end example of inputting a claim to a journey, and then using it in this journey (e.g. pre-conditions or storage) as well as outputting it from the journey, can be found in this "Implementing an invitation flow" document (which I was author of).
The high-level solution is:
1) At design-time, configure the relying party policy with the input claim.
<RelyingParty>
<DefaultUserJourney ReferenceId="SignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<InputTokenFormat>JWT</InputTokenFormat>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_MySharedSecret" />
</CryptographicKeys>
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_Test" />
</InputClaims>
<OutputClaims>
...
<OutputClaim ClaimTypeReferenceId="extension_Test" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>
You must create a policy key (in the above example, this is called "MySharedSecret", but it can be called anything) containing a shared secret that is known to the application that is invoking this policy (where the client secret for this application can be this shared secret).
2) At runtime, create a self-issued JWT containing the input claim, sign this JWT with the shared secret, and then add the JWT to the authentication request using the "client_assertion_type" and "client_assertion" parameters.
The code example for this can be found in the Wingtip sample.
An example of the authentication request is:
https://login.microsoftonline.com/b2ctechready.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1a_invitation&...&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGci...7m9s&state=CfDJ8EPk...Et0w