We are trying to support azure B2C in our web application (the application runs on a custom web host). We already integrated with B2B, but we are unable to integrate with B2C yet.
We are using the azure b2c application that is constructed in the following read-me: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/4-WebApp-your-API/4-2-B2C. We did not set the Implicit grant and hybrid flows checkboxes for our application since authentication is handled by our backend. The application works when we use the supplied code, but it fails with the ConfidentialClientApplication class.
We cannot acquire a token from the ConfidentialClientApplication class when using the methods AcquireTokenByAuthorizationCode. The method fails with the error: 'Policy 'B2C_1_signup_signin' does not contain a AuthorizationTechnicalProfile with a corresponding ClientAssertionType'.
We tried to change the replay Url type to Spa to prevent the AuthorizationTechnicalProfile error. After this change, the error 'The supplied code_verifier is invalid' is thrown instead. So, this did not solve our problem.
We can get a valid token when we build a PublicClientApplication that makes use of the method AcquireTokenInteractive. However, we cannot use this since we are in a web environment.
The issue can be reproduced with the following code snippet. In our environment, the variable code is received from signing into azure B2C. I replaced it with a variable in this example:
var code = "xxxxxxxxxxxxx";
var redirectUri = $"https://xxx.xxxxxxxxxx.com:8080/api/external_authentication/app";
var clientId = "000000000-0000-0000-0000-000000000000";
var tenantName = "tenantName";
var policySignUpSignIn = "B2C_1_signup_signin";
var certificateThumbprint = "0000000000000000000000000000000000000000";
var tenant = $"{tenantName}.onmicrosoft.com";
var apiScopes = new [] { $"https://{tenant}/helloapi/demo.read" };
var azureAdB2CHostname = $"{tenantName}.b2clogin.com";
var authorityV2 = $"https://{azureAdB2CHostname}/tfp/{tenant}/{policySignUpSignIn}";
var test = ConfidentialClientApplicationBuilder.Create(clientId)
.WithB2CAuthority(authorityV2)
.WithRedirectUri(redirectUri)
.WithCertificate(ReadCertificate(certificateThumbprint, StoreLocation.LocalMachine))
.Build();
try
{
var userToken = await test.AcquireTokenByAuthorizationCode(apiScopes, code).ExecuteAsync(); //Exception: The supplied code_verifier is invalid
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Edit: the whole question is updated because of new insights.