问题
I have a custom attribute which I'd like to use while authenticating. For example, I have another status extension attribute which can have possible values like expired/blocked/inactive/active. While creating the user I will ensure there is a value populated for this.
At the time of login I'd like to consider this extension attribute as well. It may be possible that the user is entering the right password, but just because his extension attribute status has a value of expired/blocked/inactive I'd like to deny login and give a custom localized error message.
Note: I'm using custom policies.
回答1:
You can build claims transformations to determine whether the user account is activated and, if not, display an error message.
Firstly, you must declare a claim type that represents whether the user account is activated:
<ClaimType Id="accountActivated">
<DisplayName>Account Activated</DisplayName>
<DataType>boolean</DataType>
</ClaimType>
Next, you must declare a CompareClaimToValue claims transformation to determine whether the custom attribute is set to "Active":
<ClaimsTransformation Id="CheckAccountActivated" TransformationMethod="CompareClaimToValue">
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_AccountStatus" TransformationClaimType="inputClaim1" />
</InputClaims>
<InputParameters>
<InputParameter Id="compareTo" DataType="string" Value="Active" />
<InputParameter Id="operator" DataType="string" Value="equal" />
<InputParameter Id="ignoreCase" DataType="string" Value="true" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="accountActivated" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
Next, you must declare an AssertBooleanClaimIsEqualToValue claims transformation to ensure that the user account is activated:
<ClaimsTransformation Id="EnsureAccountActivated" TransformationMethod="AssertBooleanClaimIsEqualToValue">
<InputClaims>
<InputClaim ClaimTypeReferenceId="accountActivated" TransformationClaimType="inputClaim" />
</InputClaims>
<InputParameters>
<InputParameter Id="valueToCompareTo" DataType="boolean" Value="true" />
</InputParameters>
</ClaimsTransformation>
Next, you must invoke the EnsureAccountActivated claims transformations from a copy of the AAD-UserReadUsingObjectId technical profile test that the user account is activated:
<TechnicalProfile Id="AAD-UserReadUsingObjectId-EnsureAccountActivated">
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CheckAccountActivated" />
<OutputClaimsTransformation ReferenceId="EnsureAccountActivated" />
</OutputClaimsTransformations>
<IncludeTechnicalProfile ReferenceId="AAD-UserReadUsingObjectId" />
</TechnicalProfile>
Lastly, you must invoke the AAD-UserReadUsingObjectId-EnsureAccountActivated technical profile from a copy of the SelfAsserted-LocalAccountSignin-Email technical profile to show the error message:
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-Email-EnsureAccountActivated">
...
<Metadata>
...
<Item Key="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Whoops, your e-mail address hasn't been verified, contact Support.</Item>
</Metadata>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
<ValidationTechnicalProfile ReferenceId="AAD-UserReadUsingObjectId-EnsureAccountActivated" />
</ValidationTechnicalProfiles>
...
</TechnicalProfile>
UPDATE: 3 April 2019
This worked absolutely fine however need some help regarding localizing the custom error message.
You can customize the error message using localization.
The first step is to enable localization for English and any other languages to be supported:
<BuildingBlocks>
...
<ContentDefinitions />
<Localization>
<SupportedLanguages DefaultLanguage="en">
<SupportedLanguage>en</SupportedLanguage>
<SupportedLanguage>es</SupportedLanguage>
</SupportedLanguages>
</Localization>
</BuildingBlocks>
The second step is to define the localized strings for each supported language for the page definition that is associated with the SelfAsserted-LocalAccountSignin-Email-EnsureAccountActivated technical profile:
<BuildingBlocks>
...
<Localization>
<SupportedLanguages />
<LocalizedResources Id="api.signuporsignin.en">
<LocalizedStrings>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Whoops, your e-mail address hasn't been verified, contact Support.</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
<LocalizedResources Id="api.signuporsignin.es">
<LocalizedStrings>
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfClaimsTransformationBooleanValueIsNotEqual">Vaya, su dirección de correo electrónico no ha sido verificada, contacte a Soporte.</LocalizedString>
</LocalizedStrings>
</LocalizedResources>
</Localization>
</BuildingBlocks>
(I don't speak Spanish so apologies if this is the incorrect translation.)
The last step is to declare references from the page definition to the localized resources:
<BuildingBlocks>
...
<ContentDefinitions>
<ContentDefinition Id="api.signuporsignin">
...
<LocalizedResourcesReferences MergeBehavior="Prepend">
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.signuporsignin.en" />
<LocalizedResourcesReference Language="es" LocalizedResourcesReferenceId="api.signuporsignin.es" />
</LocalizedResourcesReferences>
</ContentDefinition>
</ContentDefinitions>
<Localization />
</BuildingBlocks>
来源:https://stackoverflow.com/questions/55291570/prevent-deny-login-to-user-based-on-extension-attribute