1
votes

First I'm describing how I setup my applications then I will describe how I'm using the APIs.

Setup

  1. In my Azure Active Directory, I have two applications registered: UI and Backend
  2. UI has the client ID clientId1 and backend has client ID clientId2 (it's a GUID, but for simplicity)
  3. Both are under the same tenant tentant1 (single tenant)

Backend (Web API)

  1. Backend has an exposed API with scope "api://clientId2/access_as_user" and authorized client "clientId1" with the scope just mentioned selected
  2. I'm using passport and passport-azure-ad (I pretty much copied https://github.com/Azure-Samples/active-directory-javascript-nodejs-webapi-v2).
  3. My config:

    const config = {
        identityMetadata: "https://login.microsoftonline.com/tenant1/v2.0/.well-known/openid-configuration",
        clientID: "clientId2",
        validateIssuer: false,
        loggingLevel: 'info',
        passReqToCallback: false,
        loggingNoPII: false
    };
    
  4. I get this message when starting the server:
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":16052,"level":40,"msg":"Production environments should always validate the issuer.","time":"2020-04-11T13:25:44.283Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":16052,"level":30,"msg":"In BearerStrategy constructor: created strategy with options {\"identityMetadata\":\"https://login.microsoftonline.com/tenant1/v2.0/.well-known/openid-configuration\",\"clientID\":\"clientId2\",\"validateIssuer\":false,\"loggingLevel\":\"info\",\"passReqToCallback\":false,\"loggingNoPII\":false,\"clockSkew\":300,\"allowMultiAudiencesInToken\":false,\"audience\":[\"clientId2\",\"spn:clientId2\"]\"isB2C\":false,\"_isCommonEndpoint\":false}","time":"2020-04-11T13:25:44.285Z","v":0}
Listening on port 5000

UI (Angular SPA)

  1. UI has permissions was granted automatically permission to access Microsoft Graph (profile, user.read, user.read.all -- last one I think I granted). The permissions are in "API permissions"
  2. I went ahead and also granted access to the Backend access_as_user
  3. For the UI code I'm using the MSAL library and again I pretty much copied the repo (https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-angular)
  4. In the protectedResourceMap field I added the following
 ['https://graph.microsoft.com/v1.0/me', ['user.read']],
 ['http://localhost:5000', ['api://clientId2/access_as_user']],
  1. I am able to log in and read my user profile, but when trying to access http://localhost:5000/hello (protected), I'm getting the error the title of this question
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":20720,"level":30,"msg":"authentication failed due to: jwt audience is invalid","time":"2020-04-11T13:38:08.700Z","v":0}

--

I can see the Bearer Token coming (in the UI and backend), the server decodes the token (I can see all my profile info in the server logs), but it's saying the JWT is invalid?!

I'm not defining an audience, yet I can see in the token when it gets decoded the audience with aud: 'api://clientId2'.

I can also see when the backend starts it shows the audience as [clientId2, sps:clientId2] by default (step4 on the backend). When I define in the config audience: 'api://clientId2', I get a 403 with the message:

{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":12644,"level":30,"msg":"In Strategy.prototype.jwtVerify: We did not pass Req back to Callback","time":"2020-04-11T16:19:30.398Z","v":0}

Any help would be appreciated. Thank you.

1

1 Answers

1
votes

Turns out their code in the repository is not using proper configuration to verify the scope access...

https://github.com/Azure-Samples/active-directory-javascript-nodejs-webapi-v2/blob/master/index.js#L41

        if (req.authInfo['scp'].split(" ").indexOf("demo.read") >= 0) {

I needed to change the scope from "demo.read" to "access_as_user".