Search code examples
azure-active-directoryjwtsharepoint-onlinebearer-tokencsom

Azure AD Bearer Token has wrong "aud" claims


I am trying to use AAD delegated permission Bearer tokens for a Visio VSTO addin to create SharePoint Online pages using CSOM. Initially I was able to get this working entering username / password following Modern Authentication with CSOM for Net Standard

However, I would like for the user to select an existing AAD account. When I attempt to use the following code the Bearer token "aud" claim is consistently set to "00000003-0000-0000-c000-000000000000" which is the Graph API. Whilst a ClientContext object is returned I am getting a HTTP 401 Unauthorized error when performing a page lookup.

The code is as follows

            //
            // Get Client App
            //
            var ClientApp = (PublicClientApplication)PublicClientApplicationBuilder.Create(<AAD App ID>)
           .WithDefaultRedirectUri()
           .WithTenantId(<AAD Tenant ID>)
           .WithAuthority(AzureCloudInstance.AzurePublic, <AAD Tenant ID>)
           .Build();
            
            //
            // Prompt for user to select preferred AAD account
            // The returned JWT Bearer Token "aud" claim is 00000003-0000-0000-c000-000000000000
            //
            var Token = ClientApp.AcquireTokenInteractive(scopes)
              .WithPrompt(Prompt.SelectAccount)
              .WithParentActivityOrWindow(GetActiveWindow())
              .ExecuteAsync()
              .GetAwaiter()
              .GetResult();

            //
            // Get client Context
            //
            var ClientContext = AuthenticationManager.GetAzureADAccessTokenAuthenticatedContext(<SharePoint Site URL>, Token.AccessToken);

            //
            // Using the Client Context to query the Site results in HTTP 401
            //
           ClientContext.Load(ClientContext.Web, p => p.Title, t => t.Description);
           ClientContext.ExecuteQuery();

Looking at the code for the AuthenticationManager class in the above link I can see that the AAD Bearer request is passing the following resource request parameter to the SharePoint online URL:

var body = $"resource={resource}&client_id={clientId}&grant_type=password&username={HttpUtility.UrlEncode(username)}&password={HttpUtility.UrlEncode(password)}";

So it seems that AAD is setting the Bearer token "aud" claim based upon this parameter. However, when I try and add this parameter using 'WithExtraQueryParameters' I am getting the following error: "AADSTS901002: The 'resource' request parameter is not supported"


Solution

  • Ok, I figured out the problem. The scope needs to be prefixed with the resource:

    string[] scopes = { "https://<domain>.sharepoint.com/AllSites.Write", "user.read" }
    

    Then retrieve the token

     this.Token = await ClientApp.AcquireTokenInteractive(scopes)
                                                    .WithPrompt(Prompt.SelectAccount)
                                                    .WithParentActivityOrWindow(GetActiveWindow())
                                                    .ExecuteAsync();