Tom Troughton
Tom Troughton

Reputation: 4325

"Tenant does not have a SPO license" when trying to access drive items with GraphAPI

I'm trying to understand how to configure a dotnet core web app to let me sign in using a personal Microsoft account and browse my OneDrive files.

Firstly, I've used the Microsoft Graph Explorer, signed in using the account I want to use, and verified that I can browse my drive. There it tells me the query URL is https://graph.microsoft.com/v1.0/me/drive/root/children and that it's using v1.0 of the Graph API. There's even a c# code snippet tab that shows me this:

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var children = await graphClient.Me.Drive.Root.Children
    .Request()
    .GetAsync();

So, in my dotnet core web app I've done the following. In Startup:

    string[] initialScopes = Configuration.GetValue<string>("GraphApi:Scopes")?.Split(' ');
        
        services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
            .AddMicrosoftGraph(Configuration.GetSection("GraphApi"))
            .AddInMemoryTokenCaches();

In appsettings.json:

  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<my-domain>.onmicrosoft.com",
    "TenantId": "<tenant-guid-identifier>",
    "ClientId": "<client-id>",
    "ClientSecret": "<client-secret>",
    "CallbackPath": "/signin-oidc"
  },
  "GraphApi": {
    "BaseUrl": "https://graph.microsoft.com/v1.0",
    "Scopes": "user.read files.read.all"
  }

And a test controller:

    [Authorize]
    public class OneDriveController : Controller
    {
        private readonly GraphServiceClient _graphServiceClient;

        public OneDriveController(GraphServiceClient graphServiceClient)
        {
            _graphServiceClient = graphServiceClient;
        }

        [AuthorizeForScopes(ScopeKeySection = "GraphApi:Scopes")]
        public async Task<IActionResult> Index()
        {
            var user = await _graphServiceClient.Me.Request().GetAsync();

            var driveItems = await _graphServiceClient.Me.Drive.Root.Children.Request().GetAsync();

            return Json(new
            {
                user = user.DisplayName,
                items = driveItems.Count
            });
        }
    }

For the client credentials I've created an app registration in my Azure portal with Graph API peermissions user.read and files.read.all set, and added a client secret. The authentication part I'm not so sure about. Even though I use the same personal Microsoft account to access Azure Portal and OneDrive this isn't an enterprise scenario so I opted for multitenant access.

When I run this app and browse to the route handled by my test controller I am redirected to the Microsoft OAuth flow where I sign in. Back in the app the line _graphServiceClient.Me.Request().GetAsync() returns the user profile of the account I just signed in with. However, the next line (_graphServiceClient.Me.Drive.Root.Children.Request().GetAsync()) throws an exception:

ServiceException: Code: BadRequest Message: Tenant does not have a SPO license

My understanding is that SPO means SharePoint Online and this is suggesting that an enterprise license is required for this request. However, I've already confirmed via Graph Explorer that it should be possible.

I did try the other authentication options - personal accounts only and all accounts - but in both cases I received a different error:

"'xxxxxxxxxxx'(AppName) is configured for use by Microsoft Account users only. Please use the /consumers endpoint to serve this request"

I haven't found any help online that explains this issue so seeking advice please.

Upvotes: 0

Views: 1484

Answers (1)

Carl Zhao
Carl Zhao

Reputation: 9511

Okay, let me explain your doubts.

First of all, you misunderstood what I said in the comments. I’m just asking if you set the support account type to: Personal Microsoft accounts only when creating the application. I just ask you for verification, not suggest you do it. Because this may be the cause of the error :'xxxxxxxxxxx'(AppName) is configured for use by Microsoft Account users only. Please use the /consumers endpoint to serve this request.

According to the documentation. The /tenant id or /contoso.onmicrosoft.com endpoint only allows users with work/school accounts of a specific Azure AD tenant to log in to the application. It does not support personal accounts.

Only the /common and /consumers endpoints will allow personal Microsoft accounts to log in to the application. Because you can get the correct response only by using your personal account, so you only need to log in using the /common endpoint.

Upvotes: 2

Related Questions