iOS devices support an attribute on password fields called passwordrules, which define specific, client-side password rules, such as min/max length, special characters, and restricted characters. You can learn more about passwordrules from the iOS documentation, along with a passwordrules generator .
This sample uses the following components in order to insert a passwordrules attribute into a password field:
- Custom claim (
pwdrulesin this sample) - ClaimsTransformation Technical Profile to set the rules
- Specifying the
pwdrulesas a query string parameter for loading the custom Sign-Up template - A custom Sign-Up template provided by an Azure App Service (or any other way to host dynamic content)
The pwdrules custom claim is defined as such:
<ClaimsSchema>
<ClaimType Id="pwdrules">
<DisplayName>password rules</DisplayName>
<DataType>string</DataType>
<UserInputType>Paragraph</UserInputType>
</ClaimType>
</ClaimsSchema>The pwdrules claim is populated using a ClaimsTransformation Technical Profile:
<TechnicalProfile Id="Get-Parameters">
<DisplayName>Profile to populate calims with parameters</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
</Metadata>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="pwdrules" DefaultValue="minlength: 20; maxlength: 100; required: lower; required: upper; required: digit; required: [-];" AlwaysUseDefaultValue="true"/>
</OutputClaims>
</TechnicalProfile>The OutputClaim for pwdrules is obtained using the passwordrules generator/validation tool from Apple.
In the RelyingParty, the pwdrules claim is specified as a query string parameter, and will be passed to the location of the custom Sign-Up page so that the rules can be injected into the template. The pwdrules claim is specified as a Query String parameter using the ContentDefinitionParameters section of the Relying Party.
<RelyingParty>
<DefaultUserJourney ReferenceId="PasswordRulesSignUpOrSignIn" />
<UserJourneyBehaviors>
<JourneyInsights TelemetryEngine="ApplicationInsights" InstrumentationKey="{Settings:AppInsightsKey}" DeveloperMode="true" ClientEnabled="false" ServerEnabled="true" TelemetryVersion="1.0.0" />
<ContentDefinitionParameters>
<Parameter Name="pwdrules">{Claim:pwdrules}</Parameter>
</ContentDefinitionParameters>
<ScriptExecution>Allow</ScriptExecution>
</UserJourneyBehaviors>
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" DefaultValue="none" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="local" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>The sign-up template is obtained from an MVC site as the passwordrules attribute needs to be dynamically injected (and so a static storage location, like Azure Storage, isn't available). In this example, the MVC site exposes a controller action for the rules sign-up template, taking the pwdrules query string and adding it to the ViewData dictionary. The _Layout.cshtml file acquires that value from ViewData and then applies it to any input controls of type password in the template.
This example is very simplistic, and your scenario may be more complicated and could require additional controller actions, additional view layouts, etc.
The MVC site is then referenced by the ContentDefinition for sign-up as such:
<ContentDefinitions>
<ContentDefinition Id="api.localaccountsignup.rules">
<LoadUri>https://<your-app-service-name>.azurewebsites.net/rules</LoadUri>
<RecoveryUri>~/common/default_page_error.html</RecoveryUri>
<DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.10</DataUri>
<Metadata>
<Item Key="DisplayName">Local account sign up page</Item>
</Metadata>
</ContentDefinition>
</ContentDefinitions>One thing to keep in mind is that when deploying the MVC app that provides the Sign-Up, you need to enable CORS for the B2C tenant (https://.b2clogin.com). If you do not enable CORS, then your template will not load and an error will be thrown when accessing the sign-up page.
This sample uses the SocialAndLocalAccounts starter pack as a base.
There is a healthy discussion about the passwordrules attribute here.