Christoph Wille
Christoph Wille

Reputation: 311

Create OAuth2PermissionGrant for Resources via Graph

My scenario is to create app & spn via AAD Graph. That ist rather easy (with a redirect for browser-based consent), what I now want to do is consent the spn right away (like you can do in the portal). The code itself is straight-forward:

var g = new OAuth2PermissionGrant();
g.ClientId = thePrincipal.ObjectId;
g.ConsentType = "AllPrincipals";
g.PrincipalId = null;
g.ResourceId = ##resourceId##;
g.ExpiryTime = DateTime.Now.AddYears(10);
g.Scope = "User.Read";
await client.Oauth2PermissionGrants.AddOAuth2PermissionGrantAsync(g);

Now the part that I haven't figured out properly is ##resourceId##. This is supposed to be the resourceId - in the code sample, it should be Windows Azure Active Directory. How do I get the resourceId for eg the following required resource access (00000002-0000-0000-c000-000000000000):

RequiredResourceAccess =
    new [] {
        new RequiredResourceAccess() {
                ResourceAppId = "00000002-0000-0000-c000-000000000000",
                    ResourceAccess = new [] {
                        new ResourceAccess() {
                            Id = new Guid("311a71cc-e848-46a1-bdf8-97ff7156d8e6"), // sign in and read profile (delegated perm)
                                Type = "Scope"
                        },

The lookup ResourceAppId -> resourceId (app to spn) is what I am missing. For eg AAD, Graph, manage.office.com et al.

Upvotes: 0

Views: 2099

Answers (1)

Philippe Signoret
Philippe Signoret

Reputation: 14336

From the documentation for the OAuth2PermissionGrant entity, the resourceId field of an OAuth2PermissionGrant is the objectId of the ServicePrincipal object for the resource:

Specifies the objectId of the resource service principal to which access has been granted.

So, from the tenant in which you are creating the OAuth2PemrissionGrant, you need to retrieve the ServicePrincipal object corresponding to the resource app you would like to grant permission to, and from that object, read the objectId property.

If you have the resource app's AppId, you can retrieve the corresponding ServicePrincipal object (if one exists) with:

GET https://graph.windows.net/{tenant}/servicePrincipals
        ?$filter=appId eq '{app-id-guid}'
        &api-version=1.6

With Microsoft.Azure.ActiveDirectory.GraphClient (which I think is what you're using in your code), you would do this with:

graphClient.ServicePrincipals.Where(sp => sp.AppId == "{app-id-guid}")

If what you have to identify the resource app is not the Guid app ID, but a (somewhat) friendly identifier URI (e.g. "https://graph.microsoft.com"), you can retrieve the matching ServicePrincipal object by filtering on servicePrincipalNames.

With Azure AD Graph:

GET https://graph.windows.net/{tenant}/servicePrincipals
        ?$filter=servicePrincipalNames/any(n:n eq 'https://graph.microsoft.com'))
        &api-version=1.6

With Microsoft.Azure.ActiveDirectory.GraphClient:

graphClient.ServicePrincipals
    .Where(sp => sp.ServicePrincipalNames.Any(n => n == "https://graph.microsoft.com"))

Upvotes: 1

Related Questions