AzureAD / microsoft-authentication-library-for-js

Microsoft Authentication Library (MSAL) for JS
http://aka.ms/aadv2
MIT License
3.64k stars 2.65k forks source link

Access Token generated with version 1.0, is it expected? #3414

Closed vinusorout closed 3 years ago

vinusorout commented 3 years ago

Core Library

@azure/msal-browser

Core Library Version

2.13.1

Wrapper Library

@azure/msal-angular

Wrapper Library Version

2.0.0-beta.3

Description

Access token generated for the resource is in version v1.0.

MSAL Configuration

{
    auth: {
      clientId: "xxx",
      redirectUri: "http://localhost:4200",
      postLogoutRedirectUri: "http://localhost:4200",
      authority: "https://login.microsoftonline.com/<tenant id>/",
    },
    cache: {
      cacheLocation: BrowserCacheLocation.LocalStorage,
      storeAuthStateInCookie: false, // set to true for IE 11
    },
  }

Protected Resources:
protectedResourceMap.set("https://graph.microsoft.com/v1.0/me", ["user.read"]);
  protectedResourceMap.set("http://localhost:3000/**/*", ["client_id/User.Read"]);

Relevant Code Snippets

No response

Identity Provider

Azure AD / MSA

Source

Internal (Microsoft)

Hello Team,

I have registered a new SPA app in azure portal, with Authorization Code Flow with PKCE and Access tokens (used for implicit flows), ID tokens (used for implicit and hybrid flows) both are unchecked. In API Permission section the default are available:

API Permission

My authentication is working fine, and when I check the ID Token at https://jwt.io/, I find that it is of version v2.0 ("ver": "2.0")

In my application I am trying to access an API which uses the same client_id as of my angular application. Following are my protected resources: const protectedResourceMap = new Map<string, Array>(); protectedResourceMap.set("https://graph.microsoft.com/v1.0/me", ["user.read"]); protectedResourceMap.set("http://localhost:3000//*", ["a1b5d359-3288-4ae9-b554-93777b7bd2f8/User.Read"]);**

This generates the access token but when I check the token at https://jwt.io/, I find that it is of version v1.0("ver": "1.0")

Could you please let me know, how can I create Access token of version 2.0 when the application Id used by my angular application and node API are same?

NOTE: When I use protectedResourceMap.set("http://localhost:3000//*", ["User.Read"]);, then I get an Invalid Signature Access token. JsonWebTokenError: invalid signature**

NOTE2: Even after exposing the API and adding the scope, application still generates the token in v1.0 protected resource after scope addition: protectedResourceMap.set("http://localhost:3000//*", ["api://a1b5d359-3288-4ae9-b554-93777b7bd2f8/Access.API"]);**

Scopes:

scope
vinusorout commented 3 years ago

Seems like this is expected, as I check one of the sample in that too, token used while getting the profile, has ver 1.0. Could you please provide more details why it is different for Id Token and Access Token?

svrooij commented 3 years ago

The application registration in Azure AD determines the expected version for the access token. If not specified it defaults to a v1 access token.

This is build because you can also have the client application registration in a different tenant (when using some thirth party api). It would be inconvenient if the client application can determine the token version for the api.

So when calling the graph api, there is an app registration for that with the the token version configured.

If you want to switch to v2 tokens check out https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-app-manifest#accesstokenacceptedversion-attribute on how to do that.

The version of the identity token is determined by the endpoint version, so it's possible to have an ID token with V2 and an access token with V1

sameerag commented 3 years ago

Thanks @svrooij! @vinusorout please let me know if you need anything else. Also do you guys think you will benefit from adding this detail in the docs in this repo?

vinusorout commented 3 years ago

Thanks @svrooij, I will try the step ! @sameerag I have two applications in my azure portal:

  1. test-msal-2, for which Authentication mode is enabled and is exposing an API too with a scope: scope

Currently I haven't configured any API permission on this app, except graph API:

apiperm
  1. app-implicit-flow, for which ID Token and Hybrid checkbox are checked, and this too is exposing an API: scope2

Currently I haven't configured any API permission on this app, except graph API:

apiperm2

Following are my msal configurations in angular client:

{
    auth: {
      clientId: "a1b5d359-3288-4ae9-b554-93777b7bd2f8", // **of test-msal-2**
      redirectUri: "http://localhost:4200",
      postLogoutRedirectUri: "http://localhost:4200",
      authority: "https://login.microsoftonline.com/<tenant id>/",
    },
    cache: {
      cacheLocation: BrowserCacheLocation.LocalStorage,
      storeAuthStateInCookie: false, // set to true for IE 11
    },
  }

Protected Resources:
protectedResourceMap.set("https://graph.microsoft.com/v1.0/me", ["user.read"]);
  protectedResourceMap.set("http://localhost:3000/**/*", ["api://a9863082-8dd7-429f-a518-5de001cc23a3/Access.API"]);  // **of application app-implicit-flow**

I am expecting application to break while getting the Access token for api://a9863082-8dd7-429f-a518-5de001cc23a3/Access.API because I havent configured it to the API permissions of test-msal-2 application. But it is still generating Access token without an issue. Could you please let me know if I am missing any part here! As per my understanding an application should have delegate permission to access any other application!

svrooij commented 3 years ago

Delegated permissions van also be granted by the first application that tries to access. You don't need to grant that permission ahead of time.

On Thu, 8 Apr 2021, 18:50 Vinay Sorout, @.***> wrote:

Thanks @svrooij https://github.com/svrooij, I will try the step ! @sameerag https://github.com/sameerag I have two applications in my azure portal:

  1. test-msal-2, for which Authentication mode is enabled and is exposing an API too with a scope:

[image: scope] https://user-images.githubusercontent.com/27411868/114063968-cc0ff600-98b6-11eb-8e3d-3eda0cea5c57.PNG

Currently I haven't configured any API permission on this app, except graph API: [image: apiperm] https://user-images.githubusercontent.com/27411868/114064228-08435680-98b7-11eb-90c9-1bcbcba3661c.PNG

  1. app-implicit-flow, for which ID Token and Hybrid checkbox are checked, and this too is exposing an API:

[image: scope2] https://user-images.githubusercontent.com/27411868/114064438-48a2d480-98b7-11eb-96d1-a83f96e368ff.PNG

Currently I haven't configured any API permission on this app, except graph API: [image: apiperm2] https://user-images.githubusercontent.com/27411868/114064576-68d29380-98b7-11eb-836a-795de69a896e.PNG

Following are my msal configurations in angular client:

{ auth: { clientId: "a1b5d359-3288-4ae9-b554-93777b7bd2f8", // of test-msal-2 redirectUri: "http://localhost:4200", postLogoutRedirectUri: "http://localhost:4200", authority: "https://login.microsoftonline.com//", }, cache: { cacheLocation: BrowserCacheLocation.LocalStorage, storeAuthStateInCookie: false, // set to true for IE 11 }, }

Protected Resources: protectedResourceMap.set("https://graph.microsoft.com/v1.0/me", ["user.read"]); protectedResourceMap.set("http://localhost:3000/*/", ["api://a9863082-8dd7-429f-a518-5de001cc23a3/Access.API"]); // of application app-implicit-flow

I am expecting application to break while getting the Access token for api://a9863082-8dd7-429f-a518-5de001cc23a3/Access.API because I havent configured it to the API permissions of test-msal-2 application. But it is still generating Access token without an issue. Could you please let me know if I am missing any part here! As per my understanding an application should have delegate permission to access any other application!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/3414#issuecomment-815979860, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJ3RXSAX6NMLNNS2BMG6MLTHXND5ANCNFSM42SDEXSA .

vinusorout commented 3 years ago

Thanks @svrooij , but I didnt get this! As I havent configured the permission in any of my application, it should fail otherwise why do we need to add API permissions! As explained here https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis

Is there a way to restrict Azure to create Access Token until unless the client Application has delegated permission on resource?

svrooij commented 3 years ago

By configuring the permissions ahead of time, they show up in the consent screen at login. By not adding them you can do what you call step up authentication. First you just give permissions to seeing the profile, and if you want to access the calendar you do a new auth request with additional scopes.

What you want is app roles. That way you can restrict access to certain client apps.

vinusorout commented 3 years ago

Thanks @svrooij , your solution for the token version works fine. @sameerag yes it will be good if you can document this in this repo!

I want to know which version does Microsoft recommend Access Token with v1.0 or with v2.0? and what is the future of v1.0 access token? Will Microsoft deprecate these v1.0 access tokens in future?

svrooij commented 3 years ago

@vinusorout I disagree with you that the access token version should be documented in this library. The official Azure AD Documentation is pretty clear about it.

The access token for the web API to access resources. This string is usually a Base64-encoded JWT, but the client should never look inside the access token. The format isn't guaranteed to remain stable, and it can be encrypted for the resource. People writing code depending on access token content on the client is one of the most common sources of errors and client logic breakage.

If you ask me, you should just pick the one you like better for your API and stick with it. Since it's a configuration option in the Azure AD manifest. My guess is that they will support the v1 tokens until they stop with Azure AD (maybe in 20 years).