The scope parameter should be less strict in some of the AcquireTokenXXX methods (allow an empty set of scopes)
See original GitHub issueIs your feature request related to a problem? Please describe.
In Web scenarios, the authorization code is requested by the ASP.NET / ASP.NET core middlewre, and redeeming the code is often done with MSAL.NET, but only to have a token in the cache, so that it can be used from controllers, using AcquireTokenSilentAsync
. For instance in the Web app calls web api sample
// This initializes the ASP.NET / ASP.NET Core part
options.ResponseType = "id_token code";
options.Scope.Add("offline_access");
options.Scope.Add("User.Read");
// Handling the auth redemption by MSAL.NET so that a token is available in the token cache
// where it will be usable from Controllers later (through the TokenAcquisition service)
var handler = options.Events.OnAuthorizationCodeReceived;
options.Events.OnAuthorizationCodeReceived = async context =>
{
var _tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService<ITokenAcquisition>();
await _tokenAcquisition.AddAccountToCacheFromAuthorizationCode(context, options.Scope);
await handler(context);
};
Note that, as the name of the AddAccountToCacheFromAuthorizationCode
method tells us, the intent is just to add an account to the cache from the authorization code. For more context see active-directory-aspnetcore-webapp-openidconnect-v2 in Startup.cs#L67
The simplified implementation of AddAccountToCacheFromAuthorizationCode
is something like this:
/// <summary>
/// Scopes which are already requested by MSAL.NET. they can't be re-requested;
/// </summary>
private string[] scopesRequestedByMsalNet = new string[] { "openid", "profile", "offline_access" };
var result = await application.AcquireTokenByAuthorizationCodeAsync(context.ProtocolMessage.Code, scopes.Except(scopesRequestedByMsalNet));
For more context see active-directory-aspnetcore-webapp-openidconnect-v2 in Extensions/TokenAcquisition.cs#L71-L130
The way the token is used in controllers is described here:
public async Task<IActionResult> Contact()
{
var scopes = new string[] { "user.read" };
try
{
var accessToken = await _tokenAcquisition.GetAccessTokenOnBehalfOfUser(HttpContext, scopes);
dynamic me = await CallGraphApiOnBehalfOfUser(accessToken);
ViewData["Me"] = me;
return View();
}
catch (MsalUiRequiredException ex)
{
if (CanbeSolvedByReSignInUser(ex))
{
AuthenticationProperties properties = BuildAuthenticationPropertiesForIncrementalConsent(scopes, ex);
return Challenge(properties);
}
else
{
throw;
}
}
}
GetAccessTokenOnBehalfOfUser
really calls AcquireTokenSilentAsync
with the identity of the user signed-in with the application. For details see here
Describe the solution you’d like
Today, AcquireTokenByAuthorizationCodeAsync
,
- does not allow scopes = null
- does not allow scopes = string[0]
- does not allow scopes to contain one of the following strings { “openid”, “profile”, “offline_access” }
It should not be necessary, at that point to pass-in something in the scope parameter if the web app want to leverage dynamic consent depending on the controllers (given that MSAL.NET will already systematically add “openid profile offline_access” for the token cache to work as expected. It should also be possible to pass one of these without getting an exception.
Describe alternatives you’ve considered The work around is:
- to avoid passing the known sceopes as done in TokenAcquisition. It’s another thing that customers need to think about, and risks
- pass some random scope (“user.read”) to add the token to the cache.
Additional context
-
The same applies in Web API calling a Web API, and therefore using
AcquireTokenOnBehalfOfAsync
(as illustrated here in order toAddAccountToCacheFromJwt
): -
For PubliClientApplications, I wonder if we should allow null / empty scopes in the interactive overrides (which would mean, just sign-in a user). allowing “openid”, “profile”, “offline_access” is less crucial for them as MSAL.NET does all the work and does not need to cooperate with ASP.NET / ASP.NET Core, but this would not hurt.
-
This would not be needed for IWA or U/P (but might not hurt either)
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:20 (15 by maintainers)
Top GitHub Comments
@Mephisztoe You might find this interesting on the differences between msal v1 and v2 as well as how to migrate from v1 to v2
Are you working on a b2c app? if so, here is a nice xamarin sample that might be helpful.
And a non-b2c sample with xamarin
Can you send the stack trace or error message you are getting and which platform (Android, iOS, UWP)?
Fixed in MSAL 4.12.0 release