I'm trying to configure vue-authenticate oauth2 for Microsoft Entra authentication, but I get the error:
Message: AADSTS9002325: Proof Key for Code Exchange is required for cross-origin authorization code redemption.
Found a workaround by changing response_type
to be token
instead of code
.
oauthType: '2.0',
responseType: 'token',
responseParams: {
code: 'code',
But that is returning the access_token
, which is needed to call Graph API, not the id_token
that is better suited for the authentication and authorization of your own API. See also Azure Authentication - Access Token returning wrong AUD(00000003-0000-0000-c000-000000000000)
This library uses explicit flow by default which returns code first, and then you need to do exchange for token using your own server implementation. This is more secure process.
I've also received support from Microsoft regarding this issue. During the test with the correlation ID, I verified with them that the above solution is equivalent to transitioning from Single Page Application (SPA) to Web Platform, and indeed, from the Authorization Code Flow to the Implicit Grant Flow. I'm noting this here as further confirmation of this answer.
The solution I'd suggest is Microsoft MSAL library with a code snippet like below
const { result, acquireToken } = useMsalAuthentication(InteractionType.Popup, loginRequest);
const state = reactive({
resolved: false,
data: {
}
});
async function getAPIData() {
var token = "";
if (result.value) {
try {
token = result.value.idToken
fetchDataWithToken(token)
.then(data => {
// implement your Vue's declarative rendering model
// e.g your ref datamodels ...
data.message.datamodels.forEach((datamodel, index) => {
Finally, considering my comment under the accepted answer, namely the fact that
usually it is intended that calling a resource API is subject to an authorization flow
you can easily replace the accessToken
instead of the idToken
token = result.value.accessToken
once you have defined the api scope and
export const loginRequest = {
scopes: ['api:/your-web-api-app-ID-URI/yourResource.yourOperation'],
};
Finally, in the backend API, the scope (typically defined as Resource.Operation
or often user_impersonation, without the app URI) will appear as scp
when validating the accessToken
, also known as the "user token". This information is highlighted in the Note from the Claims tab of https://jwt.ms/
:
The set of scopes exposed by your application for which the client application has requested (and received) consent. Your app should verify that these scopes are valid ones exposed by your app, and make authorization decisions based on the value of these scopes. Only included for user tokens.
For the validation in a Python API, see this answer.
My point is that access tokens, also said user tokens, are related to a consent for the api scope, which is typical of something like graph api, that requires the users to authorize the app to see their user profiles. That is very different from app roles, that can belong to the id tokens, as I initially said, and are typical of resource operations, for which a consent is not needed. In that scenario users have privileges to perform some app operations, for which it makes no sense to ask them a "consent".
In order to avoid revisiting this topic—which has been discussed several times in the past and often leads to misunderstandings, so I don't want to return to it again in the future—I am leaving here clear evidence of the use of the ID token in the frontend, taken from official Microsoft examples.
Only the ID token can be validated by the frontend. Therefore, access token validation, for those who use it, implies protection via a separate app registration for the backend, and validation of the access token in the backend. That setup is, in fact, like treating the backend as a different, third-party app. As such, access token protection applies to B2C scenarios, where third-party APIs are called by a user authenticated via delegated authentication—not to the MyOrg scenario, where the user is calling APIs of the same application as the frontend.
Instead, I am referencing an official Microsoft sample that uses the ID token on the frontend. It's particularly important to note—something many so-called “experts” overlook or discuss superficially or incorrectly—that the ID token also includes (and I repeat, includes) the claims used to authenticate the user’s roles.
.NET (Blazor) https://github.com/Azure-Samples/ms-identity-blazor-server/blob/732d7e3109e03127034edc284841e73701816245/WebApp-your-API/MyOrg/Client/Pages/UserClaimsBase.cs#L12 Note the explicit comment: “Retrieves claims present in the ID Token issued by Azure AD” referring to a client page—therefore, the frontend. namespace blazorserver_client.Pages
{
/// <summary>
/// Base class for UserClaims component.
/// Retrieves claims present in the ID Token issued by Azure AD.
/// </summary>
public class UserClaimsBase : ComponentBase
Also note (and this is the last time I’ll address it—I don’t want to come back to this again) that in the MyOrg case, unlike the B2C case, there is no Data/ToDoListService.cs folder under Client, only the Pages folder:
Whereas only in the B2C case:
does Microsoft introduce the access token.