I'm creating a custom policy that authenticates a user against their signInName, not their email. The signInName is a number between 4 and 10 digits.
I need to be able to strip any leading zeros that a person enters before their username before performing the authentication. So when a user enters 1234 or 0000001234, I need to authenticate them using only 1234.
How can I strip these zeros from the entered signInName before it is used to authenticate the user?
Here is the technical profile where authenticate occurs.
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Username">
<DisplayName>Local Account Signin</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="SignUpTarget">SignUpWithLogonEmailExchange</Item>
<Item Key="setting.operatingMode">Username</Item>
<Item Key="setting.showSignupLink">false</Item>
<Item Key="setting.forgotPasswordLinkLocation">None</Item>
<Item Key="ContentDefinitionReferenceId">api.ctas-localaccountsignin</Item>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" DefaultValue="{OIDC:LoginHint}" AlwaysUseDefaultValue="true" PartnerClaimType="signInName" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
<OutputClaim ClaimTypeReferenceId="password" Required="true" />
<OutputClaim ClaimTypeReferenceId="objectId" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" />
<OutputClaim ClaimTypeReferenceId="userPrincipalName" Required="true" />
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
</ValidationTechnicalProfiles>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>
<TechnicalProfile Id="login-NonInteractive">
<Metadata>
<Item Key="client_id">xxx</Item>
<Item Key="IdTokenAudience">xxx</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="client_id" DefaultValue="xxx" />
<InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="xxx" />
</InputClaims>
</TechnicalProfile>
The only way I found to do this was to create a new claims transformation that utilizes SetClaimsIfRegexMatch with extract groups.
The calling technical profile:
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Username">
<DisplayName>Local Account Signin</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="SignUpTarget">SignUpWithLogonEmailExchange</Item>
<Item Key="setting.operatingMode">Username</Item>
<Item Key="setting.showSignupLink">false</Item>
<Item Key="setting.forgotPasswordLinkLocation">None</Item>
<Item Key="ContentDefinitionReferenceId">api.xxx-localaccountsignin</Item>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" DefaultValue="{OIDC:LoginHint}" AlwaysUseDefaultValue="true" PartnerClaimType="signInName" />
<InputClaim ClaimTypeReferenceId="signInNameWithoutZeroes" />
<InputClaim ClaimTypeReferenceId="resultValue" />
<InputClaim ClaimTypeReferenceId="resultMatch" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
<OutputClaim ClaimTypeReferenceId="password" Required="true" />
<OutputClaim ClaimTypeReferenceId="objectId" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" />
<!--Added Claims-->
<OutputClaim ClaimTypeReferenceId="version" />
<OutputClaim ClaimTypeReferenceId="signInNameWithoutZeroes" />
<OutputClaim ClaimTypeReferenceId="resultValue" />
<OutputClaim ClaimTypeReferenceId="resultMatch" />
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="ExperimentalValidation-StripLeadingZeros" />
<ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
</ValidationTechnicalProfiles>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>
Other profiles and transformation:
<TechnicalProfile Id="ExperimentalValidation-StripLeadingZeros">
<DisplayName>Strip zeroes from signin name</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="signInNameWithoutZeroes" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="StripLeadingZeros" />
</OutputClaimsTransformations>
</TechnicalProfile>
<ClaimsTransformation Id="StripLeadingZeros" TransformationMethod="SetClaimsIfRegexMatch">
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" TransformationClaimType="claimToMatch"/>
</InputClaims>
<InputParameters>
<InputParameter Id="matchTo" DataType="string" Value="^0*(?<signInNameWithoutZeroes>.+)$" />
<InputParameter Id="outputClaimIfMatched" DataType="string" Value="You entered a femasid with leading zeroes" />
<InputParameter Id="extractGroups" DataType="boolean" Value="true" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="resultValue" TransformationClaimType="outputClaim" />
<OutputClaim ClaimTypeReferenceId="resultMatch" TransformationClaimType="regexCompareResultClaim" />
<OutputClaim ClaimTypeReferenceId="signInNameWithoutZeroes" />
</OutputClaims>
</ClaimsTransformation>