We have a web application which needs authenticated access to several Web APIs. We are using Azure AD B2C for authentication.
I understand you can not include scopes for both resources in one call.
I understand that MSAL is meant to use a refresh token that was cached from the first resource token, to request an access token for the second resource.
IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var accounts = await cca.GetAccountsAsync();
AuthenticationResult result = await cca.AcquireTokenSilent(scopeForApi2, accounts.FirstOrDefault())
When this call is made, the call doesnt not fail, but the Access Token is null.
Within Azure B2C, the web app, and webapis are registered - and the web app has been granted permission and admin consent to all the scopes from the webapis.
Is this supported using Azure AD B2C and/or MSAL.NET?
We get the first access token for the first resource api successfully:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// Generate the metadata address using the tenant and policy information
MetadataAddress = String.Format(Globals.WellKnownMetadata, Globals.Tenant, Globals.DefaultPolicy),
// These are standard OpenID Connect parameters, with values pulled from web.config
ClientId = Globals.ClientId,
RedirectUri = Globals.RedirectUri,
PostLogoutRedirectUri = Globals.RedirectUri,
// Specify the callbacks for each type of notifications
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = OnRedirectToIdentityProvider,
AuthorizationCodeReceived = OnAuthorizationCodeReceived,
AuthenticationFailed = OnAuthenticationFailed,
},
// Specify the claim type that specifies the Name property.
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
ValidateIssuer = false
},
// Specify the scope by appending all of the scopes requested into one string (separated by a blank space)
Scope = $"openid profile offline_access {Globals.ReadTasksScopeApi1} {Globals.WriteTasksScopeApi1}"
}
);
we get the first access token using the authorizationcode - we receive an access token and refresh token
IConfidentialClientApplication confidentialClient
= MsalAppBuilder.BuildConfidentialClientApplication(
new ClaimsPrincipal(notification.AuthenticationTicket.Identity));
// Upon successful sign in, get & cache a token using MSAL
AuthenticationResult result = await confidentialClient
.AcquireTokenByAuthorizationCode(Globals.Scopes_Api1, notification.Code)
.ExecuteAsync();
I have also tried adding the "resource" query parameter but it doesnt seem to make any difference:
var scope = new string[] { Globals.ReadTasksScopeApi2 };
IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var accounts = await cca.GetAccountsAsync();
AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault())
.WithExtraQueryParameters(new Dictionary<string, string>
{
// { "resource", "https://myb2c.onmicrosoft.com/api2" }, // tried appid and guid
{ "resource", "0a6ab6b5-1b88-49fe-a6cf-19f1878d3508" }
})
.ExecuteAsync();
Why is the Access Token null for the second call to AcquireTokenSilent on a second resource using Azure AD B2C?
scopeForApi2
– Jas Suri - MSFTBuildConfidentialClientApplication
usingWithB2CAuthority()
? – TiagoBrenck