I created a claims transformation that strips the leading zeroes from the signInName
typically used in the login-NonInteractive
technical profile. Claim with the leading zeroes stripped is called signInNameWithoutZeroes
. I want to use that claim to authenticate instead of signInName
.
I have adjusted the login-NonInteractive
technical profile to attempt to override the signInName
with signInNameWithoutZeroes
, but the login always fails in this scenario.
<TechnicalProfile Id="login-NonInteractive">
<Metadata>
<Item Key="client_id">xxxxxx</Item>
<Item Key="IdTokenAudience">xxxxxx</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="client_id" DefaultValue="xxxxxx" />
<InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="xxxxxx" />
<InputClaim ClaimTypeReferenceId="signInName" />
<InputClaim ClaimTypeReferenceId="signInNameWithoutZeroes" PartnerClaimType="username" Required="true"/>
</InputClaims>
</TechnicalProfile>
Here is 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.ctas-localaccountsignin</Item>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<!--<InputClaimsTransformations>
<InputClaimsTransformation ReferenceId="AssignValueToTester" />
</InputClaimsTransformations>-->
<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-AssignValueToVersion" />
<ValidationTechnicalProfile ReferenceId="ExperimentalValidation-AssignValueToTester" />
<ValidationTechnicalProfile ReferenceId="ExperimentalValidation-StripLeadingZeros" />
<!--<ValidationTechnicalProfile ReferenceId="ExperimentalValidation-StripLeadingZerosFromTesterNewRegEx" />-->
<ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
</ValidationTechnicalProfiles>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
</TechnicalProfile>
Here is the remainder of the code:
<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+(.*)$" />-->
<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>
In order to make this work, and to prevent adding code to the base policy, I had to duplicate the login-NonInteractive
technical profile from the base policy and move it up to the extensions policy.
This allowed me to configure it however I choose and not utilize the base policy which expected the signInName
.
<TechnicalProfile Id="login-NonInteractive-StrippedZeros">
<DisplayName>Local Account SignIn</DisplayName>
<Protocol Name="OpenIdConnect" />
<Metadata>
<Item Key="ProviderName">https://sts.windows.net/</Item>
<Item Key="METADATA">https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration</Item>
<Item Key="authorization_endpoint">https://login.microsoftonline.com/{tenant}/oauth2/token</Item>
<Item Key="response_types">id_token</Item>
<Item Key="response_mode">query</Item>
<Item Key="scope">email openid</Item>
<!-- <Item Key="grant_type">password</Item> -->
<!-- Policy Engine Clients -->
<Item Key="UsePolicyInRedirectUri">false</Item>
<Item Key="HttpBinding">POST</Item>
<!-- Custom Additions -->
<Item Key="client_id">aaaaaaaaaaaaaaaa</Item>
<Item Key="IdTokenAudience">aaaaaaaaaaa</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="password" Required="true" />
<InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" AlwaysUseDefaultValue="true" />
<InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" AlwaysUseDefaultValue="true" />
<InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
<InputClaim ClaimTypeReferenceId="client_id" DefaultValue="aaaaaaaaaac" />
<InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="aaaaaaaaaaaaaaaa" />
**<InputClaim ClaimTypeReferenceId="signInNameWithoutZeros" PartnerClaimType="username" Required="true"/>**
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" />
<OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" />
</OutputClaims>
</TechnicalProfile>