in order to validate if a user email exists in a given database before sign he in I'm using a RESTful API technical profile.
When I perform the sign-in flow using external IdPs (e.g. Google, Facebook, etc) it works like a charm, however, with local account sign-in flow (e.g. login and password) I get the exception above;
Here's a few information I got from Application Insights:
{
"Kind": "Headers",
"Content": {
"UserJourneyRecorderEndpoint": "urn:journeyrecorder:applicationinsights",
"CorrelationId": "97c526e1-96cd-45b6-8dd9-dfe26f26dfa5",
"EventInstance": "Event:API",
"TenantId": "foo",
"PolicyId": "B2C_1A_V2_AccountLink_SUSI"
"Kind": "HandlerResult",
"Content": {
"Result": true,
"RecorderRecord": {
"Values": [
{
"Key": "SendErrorTechnicalProfile",
"Value": "OpenIdConnectProtocolProvider"
},
{
"Key": "Exception",
"Value": {
"Kind": "Handled",
"HResult": "80131500",
"Message": "Error granting access to your user, please try again later. Validation error: Email is mandatory.",
"Data": {
"IsPolicySpecificError": false
},
"Exception": {
"Kind": "Handled",
"HResult": "80131500",
"Message": "Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details.",
"Data": {}
}
}
}
]
},
The Statebag + additional HTTP request info:
"Statebag": {
"Complex-CLMS": {
"signInName": "foo@gmail.com",
"objectId": "aaaaaaa-bbbbbb-4b0c-be57-852ca738e337",
"authenticationSource": "localAccountAuthentication",
"termsOfUseConsentRequired": "False",
"extension_termsOfUseConsentDateTime": "12/2/2021 2:30:09 PM",
"currentTime": "12/2/2021 2:39:14 PM",
"currentUserIdentities": "System.Collections.ObjectModel.Collection`1[Microsoft.Cpim.Data.UserIdentity]",
"signInNames.emailAddress": "foo@gmail.com",
"displayName": "Raphael Silva",
"givenName": "Raphael ramos",
"surname": "silva",
"issuers": "System.Collections.ObjectModel.Collection`1[System.String]"
},
"PROT": {
"c": "2021-12-02T14:39:16.1594338Z",
"k": "PROT",
"v": "AAD Request to https://graph.windows.net/<foo>/users/<bar>?api-version=1.6 using method GET as request body is malformed.\r\nResponse: \n{\"odata.metadata\":\"https://graph.windows.net/<foo>/$metadata#directoryObjects/@Element\",\"odata.type\":\"Microsoft.DirectoryServices.User\",\"objectType\":\"User\",\"objectId\":\"<bar>\",\"deletionTimestamp\":null,\"accountEnabled\":true,\"ageGroup\":null,\"assignedLicenses\":[],\"assignedPlans\":[],\"city\":null,\"companyName\":null,\"consentProvidedForMinor\":null,\"country\":null,\"createdDateTime\":\"2021-12-02T14:30:28Z\",\"creationType\":\"LocalAccount\",\"department\":null,\"dirSyncEnabled\":null,\"displayName\":\"Raphael Silva\",\"employeeId\":null,\"facsimileTelephoneNumber\":null,\"givenName\":\"Raphael ramos\",\"immutableId\":null,\"isCompromised\":null,\"jobTitle\":null,\"lastDirSyncTime\":null,\"legalAgeGroupClassification\":null,\"mail\":null,\"mailNickname\":\"<foo>\",\"mobile\":null,\"onPremisesDistinguishedName\":null,\"onPremisesSecurityIdentifier\":null,\"otherMails\":[],\"passwordPolicies\":\"DisablePasswordExpiration\",\"passwordProfile\":null,\"physicalDeliveryOfficeName\":null,\"postalCode\":null,\"preferredLanguage\":null,\"provisionedPlans\":[],\"provisioningErrors\":[],\"proxyAddresses\":[],\"refreshTokensValidFromDateTime\":\"2021-12-02T14:30:28Z\",\"showInAddressList\":null,\"signInNames\":[{\"type\":\"emailAddress\",\"value\":\"r.r.raphael.silva@gmail.com\"}],\"sipProxyAddress\":null,\"state\":null,\"streetAddress\":null,\"surname\":\"silva\",\"telephoneNumber\":null,\"thumbnailPhoto@odata.mediaEditLink\":\"directoryObjects/6207c4d7-8e54-4b0c-be57-852ca738e337/Microsoft.DirectoryServices.User/thumbnailPhoto\",\"usageLocation\":null,\"userIdentities\":[],\"userPrincipalName\":\"<foobar>\",\"userState\":null,\"userStateChangedOn\":null,\"userType\":\"Member\",\"extension_9614eff520454054b6d79fbe0c7a5491_residentialPostcode\":\"<foo>\",\"extension_9614eff520454054b6d79fbe0c7a5491_termsOfUseConsentVersion\":\"V1\",\"extension_9614eff520454054b6d79fbe0c7a5491_termsOfUseConsentChoice\":\"AgreeToTermsOfUseConsentYes\",\"extension_9614eff520454054b6d79fbe0c7a5491_termsOfUseConsentDateTime@odata.type\":\"Edm.DateTime\",\"extension_9614eff520454054b6d79fbe0c7a5491_termsOfUseConsentDateTime\":\"2021-12-02T14:30:08.7498164Z\",\"extension_9614eff520454054b6d79fbe0c7a5491_haspassword\":true}\r\n",
"p": false
}
}
}
Finally, the RESTapi technical profile:
<!-- B2C_1A_TrustFrameworkExtensions -->
<TechnicalProfile Id="REST-AuthB2CSignIn">
<DisplayName>Get User roles from the database</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<!-- Set the ServiceUrl with your own REST API endpoint -->
<Item Key="ServiceUrl">{config:SignInFunction}</Item>
<Item Key="SendClaimsIn">Body</Item>
<!-- Set AuthenticationType to Basic or ClientCertificate in production environments -->
<Item Key="AuthenticationType">None</Item>
<!-- REMOVE the following line in production environments -->
<Item Key="AllowInsecureAuthInProduction">true</Item>
</Metadata>
<InputClaims>
<!-- Claims sent to your REST API -->
<InputClaim ClaimTypeReferenceId="objectId" />
<InputClaim ClaimTypeReferenceId="email" />
<InputClaim ClaimTypeReferenceId="displayName" />
<InputClaim ClaimTypeReferenceId="givenName" />
<InputClaim ClaimTypeReferenceId="surname" />
</InputClaims>
<OutputClaims>
<!-- Claims parsed from your REST API -->
<OutputClaim ClaimTypeReferenceId="extension_Roles" />
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>