API Permissions - Microsoft Graph API - azure-active-directory

I'm using Microsoft Graph API to create an application making an HTTP request using the following documentation:
https://learn.microsoft.com/en-us/graph/api/application-post-applications?view=graph-rest-1.0&tabs=http
Example:
POST https://graph.microsoft.com/v1.0/applications
Content-type: application/json
{
"displayName": "MyAppName",
"signInAudience": "AzureADMultipleOrgs"
}
But I need to add some API permissions (Microsoft Graph Application permissions) when creating the applications so I can do other operations like getting the Azure AD groups, modify them, create users, etc. Is there a way to add and grant the permissions programmatically as well without doing it through the portal?
Thank you.

Microsoft Graph object ID
The first thing you'll need is the object ID of Microsoft Graph service principal in your tenant.
00000003-0000-0000-c000-000000000000 is the globally unique application ID for Microsoft Graph, which we can use to get the object ID by making a request like below.
GET https://graph.microsoft.com/v1.0/servicePrincipals?$filter=appid eq '00000003-0000-0000-c000-000000000000'&$select=id,appid,appDisplayName
Example response
The object ID we need is the id in the response
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals(id,appId,appDisplayName)",
"value": [
{
"id": "bd0a624d-11f8-44ab-a015-d8f276d75ad3",
"appId": "00000003-0000-0000-c000-000000000000",
"appDisplayName": "Microsoft Graph"
}
]
}
References
Application IDs for commonly used Microsoft applications
Adding API Permissions
You can add the API permissions, which is separate from granting admin consent.
PATCH https://graph.microsoft.com/v1.0/applications/{application_id}
Headers
Key
Value
Authorization
Bearer {access token}
Content-Type
application/json
Body
Key
Value
resourceAppId
The API resource to add permissions from, in this case 00000003-0000-0000-c000-000000000000 is for Microsoft Graph
resourceAccess
Array of permissions containing the ID and type
id
Use the globally unique ID of the permission want to add, which you can reference from All permissions and IDs
type
For delegated permissions, use Scope. For application permissions, use Role
Example body
The below permissions are for User.Read (delegated), openid (delegated), and Directory.Read.All (application)
{
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "37f7f235-527c-4136-accd-4a02d197296e",
"type": "Scope"
},
{
"id": "7ab1d382-f21e-4acd-a863-ba3e13f7da61",
"type": "Role"
}
]
}
]
}
References
Update application API endpoint
requiredResourceAccess resource type
resourceAccess resource type
Granting admin consent
Important to note that you can only grant admin consent with the API for delegated permissions. For application permissions, you'll need to use the Portal and click the button.
POST https://graph.microsoft.com/v1.0/oauth2PermissionGrants
Headers
Key
Value
Authorization
Bearer {access token}
Body
Key
Value
clientId
The Enterprise Application object ID for which you want to grant consent to
consentType
Indicates if authorization is granted for the client application to impersonate all users or only a specific user. AllPrincipals indicates authorization to impersonate all users. Principal indicates authorization to impersonate a specific user. Consent on behalf of all users can be granted by an administrator. Non-admin users may be authorized to consent on behalf of themselves in some cases, for some delegated permissions. Required. Supports $filter (eq only).
resourceId
Use the object ID we obtained earlier for the Microsoft Graph service principal
scope
A space-separated list of the claim values for delegated permissions which you want to grant admin consent to
Example body
{
"clientId": "7f244605-717f-408f-96fb-d369678cea56",
"consentType": "AllPrincipals",
"resourceId": "bd0a624d-11f8-44ab-a015-d8f276d75ad3",
"scope": "openid User.Read"
}
References
Create oAuth2PermissionGrant API endpoint
oAuth2PermissionGrant resource type

Unless you’re creating more then 10 applications, I would just go through the portal.
Creating secrets through the api is not very easy.
The portal has wizards and explanations for most options
Granting permissions and creating applications can be done at the same time, you can also create the application and then have an admin do the admin consent.
Admin consent explained: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#request-the-permissions-from-a-directory-admin

Related

Unable to add a Delegated Permission to an Azure AD application registration

I am new to Azure but have been messing around trying to get a feel for it. I have successfully used Azure AD to secure an API using application permissions. The typical example of creating an app role in the API registration that has an allowed member type of Application and then selecting and granting via API Permissions > Add Permission > Application Permissions of the client app registration.
Next I would like to implement OpenID Connect Authentication & Authorization where I grant a role to a user instead of the client web app. However the Delegated Permissions "tab" is not enabled. I have made sure that there is an app role created in the API as follows. I have also tried it with the app role with a allowedMemberTypes set to Users only but with the same disabled Delegated Permissions result.
Delegated Permissions Disabled:
"appRoles": [
{
"allowedMemberTypes": [
"User",
"Application"
],
"description": "Users and Applications with this role can consume the Pricing Model API",
"displayName": "Pricing Model Cosumer",
"id": "62d4b7d0-2e37-4a28-8918-098e3eabdc58",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "PricingModel.Consumer"
}
],
I have searched for hours and only found results pertaining to the Application Permissions option being disabled and the answer to this is always to verify that there is an application role to select in the specified API registration.
Is there something elsewhere that I may be missing? Is there a more appropriate way or place to ask this please let me know.
Delegated permissions are not defined in appRoles. You can add them instead in the "Expose an API" section of the app registration or in the oauth2Permissions.
To add the scope in the app registration:
Exposing delegated permissions (scopes)
Select Expose an API in the application registration.**
Select Add a scope.
If prompted, accept the proposed application ID URI (api://{clientId}) by selecting Save and Continue.
Specify these values:
Select Scope name and enter access_as_user.
Select Who can consent and make sure Admins and users is selected.
Select Admin consent display name and enter Access xxxservice as a user.
Select Admin consent description and enter Accesses the xxx web API as a user.
Select User consent display name and enter Access xxx as a user.
Select User consent description and enter Accesses the xxx web API as a user.
Keep the State value set to Enabled.
Select Add scope.
To define the delegated permissions in oauth2Permissions, see:
https://joonasw.net/view/defining-permissions-and-roles-in-aad

Azure AD: Grant an appRoleAssignment for a service principal is failing with "code": "Request_ResourceNotFound"

I am trying to create a "service principal" for application and to grant admin consent for the permissions using Microsoft graph API.
I followed the following steps:
Created application in a tenant using graph API. My request body is:
{
"displayName": "AppWithPermissions",
"requiredResourceAccess": [
{
"resourceAppId": "00000002-0000-0ff1-ce00-000000000000",
"resourceAccess": [
{
"id": "dc890d15-9560-4a4c-9b7f-a736ec74ec40",
"type": "Role"
}
]
}
]
}
Created a service principal for the above-created application. The creation was successful.
Now, I want to grant admin consent to each assigned permission programmatically using graph API.
To grant application permissions, I created an app role assignment in the appRoleAssignedTo collection of the API's service principal:
The request was as follows:
Post request:
https://graph.microsoft.com/v1.0/servicePrincipals/{id}/appRoleAssignedTo
Request body:
{
"principalId": "principal_id",
"resourceId": "resource_id",
"appRoleId": "approle_id"
}
Here,
"principal_id" is the "id" of service principal created in step 2 above.
"approle_id" is the id of the appRole you want to grant. (taken "id" value from "resourceAccess" array present in "requiredResourceAccess")
"id" in http request url and "resource_id" are the same. (taken "resourceAppId" value from "requiredResourceAccess" which is corresponds to "approle_id" given above)
After running the query, I am getting error 404.
"code": "Request_ResourceNotFound"
for the "resource_id"/"id" field.
Adding screenshots for better understandings:
App Creation:
service principal creation:
Grant an appRoleAssignment for a service principal:
I am confused about which IDs to use where and didn't get a clear idea from the documentations. Can any one please resolve my query? Thanks in advance.
It looks like you're using the appId instead of the id value.
In an app role assignment, resourceId is the id of the servicePrincipal for the resource app (in your case, the API). In an application object's requiredResourceAccess, you use appId, which is a different value.
To find the id of a service principal for which you know the appId:
GET https://graph.microsoft.com/v1.0/servicePrincipals?$filter=appId eq '{app-id}'
The response will contain the id property of the servicePrincipal object, and you can use that when creating the app role assignment.
The document description is not very clear.
In simple terms:
principalId: Usually your service principal id.
resourceId: Usually your service principal id.
appRoleId: For appRoleId you can find it by requesting GET https://graph.microsoft.com/v1.0/servicePrincipals/{id}.
Grant an appRoleAssignment for a service principal:

Azure AD & Graph API Permission

I have a variety of graph permissions assigned to different web apps in Azure. Is there any way in which I can map these graph permissions back to Azure AD roles and identify which role is the permission assigned to? I need this to implement access control based on the signed-in user
Graph permissions are granted for Azure AD app. Azure AD role is to manage Azure AD rather than API permission. There is no mapping between them.
What you are looking for is appRole.
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"displayName": "Writer",
"id": "d1c2ade8-98f8-45fd-aa4a-6d06b947c66f",
"isEnabled": true,
"description": "Writers Have the ability to create tasks.",
"value": "{the custom role name}"
}
]
A sample for your reference: Authorization in a web app using Azure AD application roles & role claims.
Update
You need to add the needed Graph permissions in Azure AD APP and then control the permissions in your code.
We assume you have assigned a custom role in an Azure AD app and added a user to this role.
When a user signs in, a token which includes the role claim will be returned.
You can judge the user's role in the code. If it matches a custom appRole, he is allowed to perform an operation, such as user-invite-all . If the user does not match any of the appRoles, he does not have permission to perform any operations.
[HttpPost]
[Authorize(Roles = "Admin, Writer, Approver")]
public ActionResult TaskSubmit(FormCollection formCollection)
{
if (User.IsInRole("Admin") || User.IsInRole("Writer"))
//do something such as inviting others.
{
Please dig deeper into the sample code I shared above.
PS: Note that I have modified the value in "appRoles" in my previous answer.

Azure AD / Microsoft Graph Access Level Upgrade and Downgrade

Is there a way to upgrade and downgrade the Azure AD / Microsoft Graph access level?
For example, can a user signup with a web app only to login and later upgrade access to One Drive or downgrade back to login? I was looking for a way to unauthorize the user access and then reauthorize with the different set of permissions but couldn't find a way to unauthorize.
You can get incremental consent if you use the V2 endpoint: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-appmodel-v2-overview.
There you can specify which scopes you want to require when redirecting the user to login.
So you can require basic ones at the start, and then if they want to enable additional features/you release an update which requires additional permissions, you can add those quite easily.
As for the other direction, no.
Once a user has given consent for some permissions, the only way to undo the consent would be to delete the oauth2PermissionGrant object mapping the user to the application's service principal.
In case of an application permission, an appRoleAssignment would need to be deleted from the service principal.
So it's possible, but you will have to call Microsoft Graph API yourself.
You can get all permission grants via: https://graph.microsoft.com/beta/oauth2PermissionGrants and it returns grant objects like this:
{
"clientId": "e846195b-9b20-4001-ad84-5ab5de5531e6",
"consentType": "AllPrincipals",
"expiryTime": "2018-05-04T09:39:32.9697945Z",
"id": "WxlG6CCbAUCthFq13lUx5s7PF6398j5LkfWqCoLpQBI",
"principalId": null,
"resourceId": "ad17cfce-f2fd-4b3e-91f5-aa0a82e94012",
"scope": "User.Read Directory.AccessAsUser.All",
"startTime": "0001-01-01T00:00:00Z"
}
This one is actually the result of admin consent (consentType = AllPrincipals and principalId = null).
For regular user consent, principalId will be the id of the user.
clientId is the id of the service principal who was granted access, and resourceId is the target service principal.
You can also filter the results to a specific user for example: https://graph.microsoft.com/beta/oauth2PermissionGrants?$filter=principalId eq '73c38a25-23eb-44eb-bf63-4aa987b2ef19'
You can then update the grant to change the approved scopes by running a PATCH to https://graph.microsoft.com/beta/oauth2PermissionGrants/WxlG6CCbAUCthFq13lUx5s7PF6398j5LkfWqCoLpQBI with a body like:
{
"scope": "User.Read"
}
You can delete the grant entirely by running a DELETE on the same URL.

Azure Active Directory: Get user's UPN with OpenID Connect authentication

I want the login system for an ASP.Net MVC 5 website be backed by Azure Active Directory.
Specifically I want to find out, whether the user is a member of a specific group and give access based on that.
I have code to query users/groups in AD, and only users from the AD get authenticated by Microsoft and redirected to the website.
But it seems that I need the user's principal name (UPN, ClaimTypes.Upn) to query the Azure AD graph API, while the OpenID Connect Provider just gives me some version of the user's e-mail address:
From OpenID Connect:
User.Identity.Name = live.com#timm#domain.tld
From AD Graph API:
user.UserPrincipalName = timm_domain#EXT#something.onmicrosoft.com
Is there any possibility to get the internal user GUID or get from one ID to the other in order to be able to query the AD graph API for the current user?
Indeed. Get the ObjectId of the user from the objectidentifier claim, using:
ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value
UPN property is set by default for regular Organizational accounts - whereas you are signing is as an MSA (Microsoft Account) external user. MSA external users do not have the UPN property set by default. That said, you do not need the user's UPN to query their Group membership using Graph API - ObjectId is recommended. Further, we recommend that for authorization purpose, you use the getMemberGroup API that returns transitive group membership of the user.
Hope this helps.
For reference on other claim types: the raw JWT access token issued by Azure AD for an MSA external user looks like this:
{
"family_name": "Guest",
"unique_name": "Live.com#aadguest#outlook.com",
"altsecid": "1:Live.com:00034001C80D80E9",
"ver": "1.0",
"aud": "https://graph.windows.net",
"acr": "1",
"iss": "https://sts.windows.net/62e173e9-301e-423e-bcd4-29121ec1aa24/",
"oid": "fa6fa59a-5f2b-4069-a8e4-c76e52179f64",
"scp": "Directory.Read UserProfile.Read",
"idp": "Live.com",
"email": "aadguest#outlook.com",
"appidacr": "1",
"given_name": "AAD",
"exp": 1403260411,
"appid": "29181964-d91b-4331-859d-d815863848d6",
"tid": "62e173e9-301e-423e-bcd4-29121ec1aa24",
"iat": 1403256511,
"amr": [
"pwd"
],
"nbf": 1403256511,
"sub": "Wi6CVQ6FVj_aj3na076wm-C6eJy6CK6YhB3PR9Jpty0"
}

Resources