I'M trying to authenticate two clients with Azure OpenId, one without client secret and another with a secret. If I'm using one or the other it works, so my app registrations in Azure are OK but I can't manage to use both in the same backend app. Here's part of my services config:
Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"), OpenIdConnectDefaults.AuthenticationScheme);
Services.AddAuthentication().AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureFormApi"), "FormAPI", "ClientFormAPI");
Services.AddControllersWithViews();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
Services.AddEndpointsApiExplorer();
Services.AddSwaggerGen();
Services.AddAuthorization();
Calls from the client without secret are like this and they work with the multiple config as show above:
[Authorize]
[HttpPost]
[Route("Download/CellSouche")]
[HasPermission(Contrats.Models.Permissions.cellsouches)]
public FileContentResult Download(DTOFormDataSelected formItems)
{
var aa = _formBO.Download(formItems);
return aa;
}
Call from a client with secrets are like this:
[Authorize(AuthenticationSchemes = "AzureFormApi")]
[Route("api/[controller]")]
[ApiController]
public class ExternalFormsController : ControllerBase
{
[HttpGet]
[Route("testapi")]
public IActionResult testapi()
{
return Ok("test");
}
}
But when I call those it returns this message: The 'ClientId' option must be provided
If I change the controller route like this:
[Authorize(AuthenticationSchemes = "FormApi")]
[Route("api/[controller]")]
[ApiController]
public class ExternalFormsController : ControllerBase
{
[HttpGet]
[Route("testapi")]
public IActionResult testapi()
{
return Ok("test");
}
}
I get this message:
No authentication handler is registered for the scheme 'FormApi'. The registered schemes are: OpenIdConnect, ClientFormAPI. Did you forget to call AddAuthentication().AddSomeAuthHandler?
What wrong? Is this in the services config or the routes?
Thanks for any clues!!
I tried a lot of services configurations, changing the order, etc. Both authentication works if I have only one in the service config.
OP adds "AllowWebApiToBeAuthorizedByACL": true
to the ClientFormAPI settings to make it work.
============================
I can reproduce the issue
This is due to configuration error when you setting the OpenID connect scheme. This part is incorrect.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureFormApi"), "FormAPI", "ClientFormAPI");
We should use .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureFormApi"), "ClientFormAPI");
and then use [Authorize(AuthenticationSchemes = "ClientFormAPI")]
in the Controller to fix the error..
public static MicrosoftIdentityWebApiAuthenticationBuilderWithConfiguration AddMicrosoftIdentityWebApi(
this AuthenticationBuilder builder,
IConfigurationSection configurationSection,
string jwtBearerScheme = JwtBearerDefaults.AuthenticationScheme,
bool subscribeToJwtBearerMiddlewareDiagnosticsEvents = false)
We need to set configuration and jwtBearerScheme in this method. "ClientFormAPI"
is recognized as Scheme name like what OpenIdConnectDefaults.AuthenticationScheme
does.
When you add parameter "FormAPI"
in the method, it becomes to use below method, then the app will try to read "FormAPI"
section in appsettings.json, which is null so that there's no ClientId
can be used to set OIDC auth and the error occurred.
public static MicrosoftIdentityWebApiAuthenticationBuilderWithConfiguration AddMicrosoftIdentityWebApi(
this AuthenticationBuilder builder,
IConfiguration configuration,
string configSectionName = Constants.AzureAd,
string jwtBearerScheme = JwtBearerDefaults.AuthenticationScheme,
bool subscribeToJwtBearerMiddlewareDiagnosticsEvents = false)