0
votes

I am trying to execute the following API using a bearer token issued to a service principal NOT an AD User. Yes I know this is the AD Graph versus Microsoft Graph endpoint, but I have my reasons :)

https://graph.windows.net/GUID-REDACTED/users/GUID-REDACTED?api-version=1.6

I get a 403 error despite the fact that I have granted all Application Permissions for "Windows Azure Active Directory" (and Microsoft Graph) to that principal. I also applied admin consent (via Grant Permissions) in the portal. Note that a request to read all users (i.e., remove last GUID off URL above) DOES succeed.

The bearer token contains the following seven claims (curiously in AD, EIGHT permissions are granted):

    "Device.ReadWrite.All",
    "Directory.Read.All",
    "Member.Read.Hidden",
    "Directory.ReadWrite.All",
    "Domain.ReadWrite.All",
    "Application.ReadWrite.OwnedBy",
    "Application.ReadWrite.All"

The token was acquired via:

 var context = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}");

 var m = new HttpRequestMessage()
 var accessToken = context.AcquireTokenAsync("https://graph.windows.net", credentials).Result.AccessToken;
 m.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

I have tried the analog of this via the Microsoft Graph endpoint, but with the ADAL AuthenticationContext and get the same 403 result. If I use the Microsoft Graph Explorer though, it works. In that case I am logged in as a user though. Upon comparing the scopes in the tokens (scp) there are differences (because the user has certain 'user' scopes), but nothing that immediately looks suspicious.
Directory.AccessAsUser.All is on the user scope but not the application identity scope, but that makes sense to me, unless that scope is (incorrectly?) required for the operation I am trying.

Any ideas what I am missing here? Is there a reference that maps the scopes/roles required to the actual API operations? Does the SP need a directory role, like a user would need?

1
Looks like this is not possible due with credential flow: stackoverflow.com/questions/45982912/…Jim O'Neil
That's correct. This is in part because there isn't a user in context using client credentials and allowing it to do something like change passwords would allow an app to basically hijack an account while obscuring the identity of the person who did it.Marc LaFleur

1 Answers

0
votes

As @MarcLaFleur said, it's not a good idea to give an application permissions to reset users' password. But if you don't have other choices you can still use client credentials flow to achieve this. But this is not recommeded unless you don't have other choices.

Solution:

You can assign Company Administrators Role to your Service principal. You can refer to this document to do that.

  1. Use AAD Powershell to Connect AAD:

Connect-AzureAD

  1. Get the Role of Company Administrator:

$role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Company Administrator'}

  1. Assign the role to your SP:

Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $yoursp.ObjectId