I implemented what is described here: Signup with email invitation
This works flawlessly when the Azure app service uses the B2C Azure AD for authentication\login, that is, the invitation e-mail is sent when I'm logged in through an account authenticated by the B2C AD.
Now I have another app service pointing to a B2B Azure AD for user login\authentication and so the invitation e-mail is sent when I'm logged in through an account authenticated by the B2B AD.
The email with the invitation link that points to the B2C AD is sent correctly. However after clicking the link, the B2C signup invitation policy takes action and I'm presented with a 401 error (unauthorized). This looks like the B2C policy can't access the metadata endpoint set in the policy configs for any reason...
The message being displayed is:
Correlation ID: 78292d04-7184-42d0-ac2d-a60bb98a532f
Timestamp: 2019-09-20 16:19:25Z AADB2C: The metadata endpoint
'https://mywebsite.azurewebsites.net/.well-known/openid-configuration'
returned the following status code: '401'
This is the custom signup invitation policy <ClaimsProvider>
in which this metadata endpoint is specified:
<!--This technical profile specifies how B2C should validate the token, and what claims you want B2C to extract from the token.
The METADATA value in the TechnicalProfile meta-data is required.
The “IdTokenAudience” and “issuer” arguments are optional (see later section)-->
<ClaimsProvider>
<DisplayName>ID Token Hint ClaimsProvider</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="IdTokenHint_ExtractClaims">
<DisplayName>ID Token Hint TechnicalProfile</DisplayName>
<Protocol Name="None" />
<Metadata>
<!-- Action required: replace with endpoint location -->
<Item Key="METADATA">https://mywebsite.azurewebsites.net/.well-known/openid-configuration</Item>
<!-- <Item Key="IdTokenAudience">your_optional_audience_override</Item> -->
<!-- <Item Key="issuer">your_optional_issuer</Item> -->
</Metadata>
<OutputClaims>
<!--Read the email claim from the id_token_hint-->
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="shardTenantId"/>
</OutputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
My question is: why this 401 (unauthorized) is being thrown? When I try to access the metadata endpoint: https://mywebsite.azurewebsites.net/.well-known/openid-configuration
it opens just fine and returns the required json
output:
{
issuer: "https://mywebsite.azurewebsites.net/",
jwks_uri: "https://mywebsite.azurewebsites.net/.well-known/keys",
id_token_signing_alg_values_supported: [
"RS256"
]
}
This is the web API method that outputs the json
described above:
[AllowAnonymous]
[Route(".well-known/openid-configuration", Name = "OIDCMetadata")]
[HttpGet]
public HttpResponseMessage Metadata()
{
var json = JsonConvert.SerializeObject(new OidcModel
{
// The issuer name is the application root path
Issuer = InvitationHelper.GetBaseUrl(),
// Include the absolute URL to JWKs endpoint
JwksUri = Url.Link("JWKS", null),
// Sample: Include the supported signing algorithms
IdTokenSigningAlgValuesSupported = new[] { SigningCredentials.Value.Algorithm }
});
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
}
I even tried adding [AllowAnonymous] annotation to the API method but that didn't make any change.
Why can't the custom signup invitation policy access the metadata endpoint that is in an app service hosted on a different B2B AD tenant?
NOTE 1: added Application Insights instrumentation to this custom policy and the only message I saw there was Fatal Exception 401 without any more valuable info:
{"Kind":"FatalException","Content":{"Time":"4:15 PM","Exception":
{"Kind":"Handled","HResult":"80131500","Message":"The
metadata endpoint
'https://mywebsite.azurewebsites.net/.well-known/openid-configuration'
returned the following status code:
'401'","Data":
{"IsPolicySpecificError":false,"uri":"https://mywebsite.azurewebsites.net/.well-known/openid-configuration"}}}}
NOTE 2: if you look at the <ClaimsProvider>
above there are these 2 settings:
<!-- <Item Key="IdTokenAudience">your_optional_audience_override</Item> -->
<!-- <Item Key="issuer">your_optional_issuer</Item> -->
I'm not sure how to use these other 2 settings as those were not described in the doc @ GitHub.
Maybe the issuer is the problem... I'm trying things here but nothing is working so far. So I decided to ask this question. I hope someone can shed some light.