Forum Discussion

Tommy-Johannessen's avatar
Tommy-Johannessen
Copper Contributor
Aug 25, 2023
Solved

Error when authenticating with Default Azure Credential (CSOM)

Before the summer break I used a code that we have developed to set up content on SharePoint sites though local host when running from Visual Studio. Then when I returned about a week later the code failed with the following error message and reasoning:

The remote server returned an error: (401) Unauthorized.
Reason: App is not allowed to call SPO with user_impersonation scope

No changes where made to the code.

 

The authentication code is implement as this:

public async Task<ClientContext> GetClientContextAsync(Uri siteUri)
{
    try
    {
        var accessToken = await GetAccessTokenAsync(siteUri.Host);
        var authManager = new AuthenticationManager();

        return authManager.GetAccessTokenContext(siteUri.ToString(), accessToken.Token);
    }
    catch (Exception ex)
    {
        logger.Error(string.Format("GetClientContextAsync (Token): {0}", ex.Message));
        return null;
    }
}

private async Task<AccessToken> GetAccessTokenAsync(string siteUrl)
{
    DefaultAzureCredential credential = new DefaultAzureCredential();
    String scope = $@"https://{siteUrl}/.default";
    AccessToken accessToken = await credential.GetTokenAsync(new TokenRequestContext(new[] { scope }));

    return accessToken;
}

Has it been any changes to the authentication method?

  • elnurrr's avatar
    elnurrr
    Oct 23, 2023
    then you will have to wait for MS reenabling SPO accepting 'user_impersonation' scope (there is a ticket already) πŸ™‚
    any other solution involves an app registration created

7 Replies

  • Perneel's avatar
    Perneel
    Copper Contributor

    Tommy-Johannessen Did you ever find a solution to this? I'm experiencing a similar issue. I'm receiving 401 Unauthorized errors while using the same way to build up a context. It's been a few months since I worked on this project, but I'm sure it worked before. Any clues?

    • elnurrr's avatar
      elnurrr
      Copper Contributor

      Perneel, here is your workaround πŸ™‚

      #if DEBUG
                  var credential = new InteractiveBrowserCredential(new InteractiveBrowserCredentialOptions() { ClientId = "the-client-id" });
      #else
                  var credential = new Azure.Identity.DefaultAzureCredential();
      #endif
      
      var token = await credential.GetTokenAsync(new Azure.Core.TokenRequestContext(new[] { "https://yourtenanthere.sharepoint.com/.default" }));
      log.LogInformation(token.Token);

       

      The app registration the 'the-client-id' refers to looks like this

       

      As a result, you are able to get an access token via the the Authorization Code Flow with PKCE and your browser while debugging your code locally in VS

       

      • Tommy-Johannessen's avatar
        Tommy-Johannessen
        Copper Contributor

        Thank you for the reply elnurrr,

         

        One of the issues with this approach is that we some times use our kode to setup SharePoint lists and content types on sites, where we only have access to that specific site and a user (often with MFA).

         

        The approach we used earlier allowed us to login with the user in Visual Studio and run the code on behalf of that user. Now that is not possible, just wanted to know if it was possible to achieve the same without making a resource in Azure.

         

        But I will keep your answer in mind as a nice workaround when possible, thanks.

Resources