Can't find AppPermissons in app manifest (Azure Active directory) - azure

As of yesterday I added a webapi and a native app to my Azure AD.
Yesterday I was able to download the WEBAPI's manifest file to add appPermissions (for delegating permissions to the native app).
Not there's no longer any appPermissions located in the manifest file, it has changed. I have tried to add new apps, and even a new AD.
Now theres only appRoles there.
Does anyone know why this is, and how I could solve this so i still can delegate permissions?
Might this be the new thing to use?
oauth2Permissions": [
{
"adminConsentDescription": "Allow the application full access to the service on behalf of the signed-in user",
"adminConsentDisplayName": "Have full access to the service",
"id": "23906603-82b7-4471-afbd-b6bcf2fe7b1a",
"isEnabled": true,
"origin": "Application",
"type": "User",
"userConsentDescription": "Allow the application full access to the service on your behalf",
"userConsentDisplayName": "Have full access to the service",
"value": "user_impersonation"
}
],

#Simon Agren is right, and that new oauth2Permissions worked for me. Just download an old existing Maninifest and you will see how it now uses the oauth2Permissions instead of the appPermissions. Remember to create a new GUID for the id attribute.
I also turned surprised when I saw that this morning :)
Cheers.

Related

How to grant access to read/write files on a sharepoint site via OAuth2

I am having trouble figuring out how to give an application read/write access to a sharepoint site.
Here's what I've done:
I made a sharepoint site
I created a microsoft azure application and authenticated users using OAuth2
I set delegated permissions on the app control panel to include Files.ReadWrite.All
I created a user who has read/write permissions to the sharepoint site and authenticated him with the app.
I have a program (in PHP) which has valid access_token and refresh_token, but when I try to upload files, I get a 403 error.
Client error: `PUT https://graph.microsoft.com/v1.0/drives/b!XxxxxxxxxxxxxxxxB/items/root:/StationMD%20Addl%20Enrollees%2020200508.xlsx:/content` resulted in a `403 Forbidden` response:
{
"error": {
"code": "accessDenied",
"message": "Access denied",
"innerError": {
Oddly enough, I was able to do this as the user who created the site, but not as a dummy user (who also has permission to read and write files)
So...
The problem seems to be app permissions. Is there a way to set application permissions for just that sharepoint site, or is Files.ReadWrite.All my only option? Can I use delegated permissions for a user who is not currently logged in, but did authenticate via OAuth2?
Some more information 5/16/20
I have two users. One is my regular account which I used to create the Sharepoint Site. The other is a "service account" used to upload files. Both users are able to edit/upload/delete files using the GUI. However, when using the API, the service user can't upload files, while the regular user can. I made sure that both users were members of the site. Using the Graph Explorer, I am able to see the drive.
https://graph.microsoft.com/v1.0/drives/b!XXXXxxxxx
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives/$entity",
"createdDateTime": "2020-04-26T11:19:17Z",
"description": "",
"id": "b!XXXXXxxxxx",
"lastModifiedDateTime": "2020-05-16T11:56:23Z",
"name": "Documents",
"webUrl": "https://xxxxxxx.sharepoint.com/sites/sftp/Shared%20Documents",
"driveType": "documentLibrary",
"createdBy": {
"user": {
"displayName": "System Account"
}
},
"owner": {
"group": {
"email": "xxxx#xxxxxx.onmicrosoft.com",
"id": "xxxxx-xx-xxxx-xxxx-xxxxxxxx",
"displayName": "sftp Owners"
}
},
"quota": {
"deleted": 2812850,
"remaining": 27487773843447,
"state": "normal",
"total": 27487790694400,
"used": 8848121
}
}
It's been quite a while since I worked with SharePoint, but I'll try to answer for the Azure AD related questions.
Oddly enough, I was able to do this as the user who created the site, but not as a dummy user (who also has permission to read and write files)
This is pretty odd. I would expect the call to work with the permissions the app has :\
Is there a way to set application permissions for just that sharepoint site, or is Files.ReadWrite.All my only option?
This one I am not sure about.
You can either give the app the delegated permission Files.ReadWrite.All which allows you to access/modify any file the user can, or you can give the application permission Files.ReadWrite.All which allows the app to access/modify any file in any site collection.
Can I use delegated permissions for a user who is not currently logged in, but did authenticate via OAuth2?
Short answer, yes.
If they authenticated at least once to your app, you got a refresh token for that user when they did.
Store that refresh token securely, and use it to get a new access token when needed.
Do note a couple things:
The refresh token itself will expire after some time (maybe 2 weeks?)
When you get a new token with that refresh token, you also get a new refresh token
Token refresh can fail due to some factors, your app should be ready for this
The user will have to authenticate again to provide a new refresh token
Based on my knowledge:
Can't limit to specific site in app permission level(limit in logic if need).
Use Application permission if want to skip user to log in.
Use permission in Microsoft Graph to access data in SharePoint if want to use graph api.

How to add application permissions to my own App on azure AD

I have created an App Registration that exposes an API and a scope.
I then create a frontend app/client with another App Registration and I can add my own API as delegated permission and ask Azure AD for a token to the API on behalf of me using normal OAuth flows.
Let's say a 3 client needs access to the API but not as a given user but as the application itself. In the UI of Azure AD, there are no "Application Permissions" for my own API when adding this 3rd API and try to give it access to an API. What is the equivalent of this and how do I set it up?
I have an older article that shows you how to do it through the manifest.
https://joonasw.net/view/defining-permissions-and-roles-in-aad
Currently there is no UI for defining app permissions, so you'll have to do it through the manifest or with PowerShell.
Essentially you need to define an appRole with an allowed member type of Application.
That is an app permission that can then be assigned to apps.
It will appear in the roles claim in the token.
{
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"displayName": "Read all todo items",
"id": "f8d39977-e31e-460b-b92c-9bef51d14f98",
"isEnabled": true,
"description": "Allow the application to read all todo items as itself.",
"value": "Todo.Read.All"
}
]
}

API Permission Issue while Azure App Registration

I have an API App registered under Azure Active Directory -> App Registrations. This API App is exposing endpoints which will be accessed by clients from within the organization. The clients are not users but background services who will accessing the endpoints.
When I am trying to grant API Permission for the clients to access the API App I see the Application Permission as disabled/greyed out. Do I need to do something different when setting the API Permissions.
Please see the attached picture.
Has anyone come across this issue or am I doing something silly. Azure Admin in our organization told me he can't help with this as he hasn't see anything like this before.
Most probably you haven't defined any roles (i.e. Application Permissions) for your app registration and hence when you try to add permissions for the client application you only see an option for Delegated Permissions.
How to define Roles/Application Permissions
Go to Azure Portal > Azure AD > App Registrations > Registration for your API application > Manifest
Find the "appRoles" collection in Manifest JSON and if it's empty, add your own appRoles here. Example:
"appRoles": [
{
"allowedMemberTypes": [
"Application"
],
"description": "Apps that have this role have the ability to invoke my API",
"displayName": "Can invoke my API",
"id": "fc803414-3c61-4ebc-a5e5-cd1675c14bbb",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "MyAPIValidClient"
}
]
Notice that I have kept "allowedMemberTypes" as "Application" so that it can only be used as Application Permission. Other possibility is to have "User" as the allowedMemberType, but that is for a different use case when you want to assign roles to users and that's not what you're looking for.
Now if you go to the client application registration to which you want to grant this role (Application Permission), you should be able to see "Application Permissions" as enabled.
You should also be able to see the Application Permission "MyAPIValidClient" with it's description available to be selected. Now I have defined only one Application Permission in example above, but as you can see it's an array, so you can define multiple ones as well. Just make sure you generate new GUID's to be assigend as "id" for each Application Permission.

How can I get the guids of Graph API permissions programmatically for an Azure AD application?

I am trying to add required permissions to an Azure AD application. I already know how to replicate information from a downloaded manifest through a PATCH REST call, e.g.
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "7b9103a5-4610-446b-9670-80643382c1fa",
"type": "Scope"
},
{
"id": "5df07973-7d5d-46ed-9847-1271055cbd51",
"type": "Scope"
}
]
}
]
As explained by Christer Ljung on his blog http://www.redbaronofazure.com/?page_id=181.
But the mystery remains how I can "convert" human-readable scopes such as Mail.Read to these obscure guids. I have read the following blog of Sahil Malik's at http://blah.winsmarts.com/2015-1-Programmatically_register_native_apps_in_Azure_AD_or_Office_365.aspx that explains how to get a list of available guids for a particular ServicePrincipal. E.g. through an http get to https://graph.windows.net/<tenant-id>/servicePrincipals()?api-version=1.6&$filter=appId%20eq%20'00000002-0000-0ff1-ce00-000000000000'> (Exchange) but when I try to get the list of available scopes of ServicePrincipal 00000003-0000-0000-c000-000000000000 (I believe the one for Graph API) the return value is just empty.
Interestingly, with Fiddler I was able to capture an http post request which contains all the guids when adding the permissions through Azure Portal.
Anyone any clue how I can do this programmatically?
After investigation, I discover a way to get permission guid using azure-cli. Share here in case anyone is finding this:
get all permisson and their GUID of a certain service principal by display-name, app-id or object-id. (Note that display-name is not unique and can maps multiple service principal)
$ az ad sp list --filter "displayName eq 'Microsoft Graph'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
$ az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table | head
Value Id UserConsentDisplayName
------------------------------------------------------- ------------------------------------ -----------------------------------------------------------------------------------------
ServiceHealth.Read.All 55896846-df78-47a7-aa94-8d3d4442ca7f Read service health
ServiceMessage.Read.All eda39fa6-f8cf-4c3c-a909-432c683e4c9b Read service messages
TermStore.ReadWrite.All 6c37c71d-f50f-4bff-8fd3-8a41da390140 Read and write term store data
TermStore.Read.All 297f747b-0005-475b-8fef-c890f5152b38 Read term store data
TeamMember.ReadWriteNonOwnerRole.All 2104a4db-3a2f-4ea0-9dba-143d457dc666 Add and remove members with non-owner role for all teams
Team.Create 7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0 Create teams
TeamsAppInstallation.ReadWriteForUser 093f8818-d05f-49b8-95bc-9d2a73e9a43c Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser 207e0cb1-3ce7-4922-b991-5a760c346ebc Allow the Teams app to manage itself for you
...
Run the below command to get full information of certain service principal including its oauth2Permissions and servicePrincipalNames, etc.
az ad sp show --id 00000003-0000-0000-c000-000000000000 >microsoft_graph_permission_list.json
# microsoft_graph_permission_list.json
{
...
"appDisplayName": "Microsoft Graph",
"appId": "00000003-0000-0000-c000-000000000000",
"objectId": "b19d498e-6687-4156-869a-2e8a95a9d659",
"servicePrincipalNames": [
"https://dod-graph.microsoft.us",
"https://graph.microsoft.com/",
"https://graph.microsoft.us",
"00000003-0000-0000-c000-000000000000/ags.windows.net",
"00000003-0000-0000-c000-000000000000",
"https://canary.graph.microsoft.com",
"https://graph.microsoft.com",
"https://ags.windows.net"
],
"appRoles": [...],
"oauth2Permissions": [
{
"adminConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read and write all users' full profiles",
"id": "204e0828-b5ca-4ad8-b9f3-f32a958e7cc4",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read and write all users' full profiles",
"value": "User.ReadWrite.All"
},
{
"adminConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
"adminConsentDisplayName": "Read all users' full profiles",
"id": "a154be20-db9c-4678-8ab7-66f6cc099a59",
"isEnabled": true,
"type": "Admin",
"userConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
"userConsentDisplayName": "Read all users' full profiles",
"value": "User.Read.All"
},
...
]
...
}
Few things to say about this topic.
First, it is important to note that all of the OAuth2Permission Scopes are registered on the main Application Object in the developer's tenant. Thus, in general, you would not have access to that information, since it would be in a tenant where you are not a user. So as an external developer, these permission scopes are not discoverable via our APIs.
Second, you are able to see that the Azure Portal has access to this information because it has elevated access to query the OAuth2Permissions for all resources in all tenants. This is how our UX is able to populate all the permissions for all the various external and internal resources that you want to use in your tenant. The portal will first check which service principals are in your tenant (service principals get provisioned most commonly once you consent to use the application), then it will look up the Application Object that corresponds to that service principal, and find all the permission scopes. This behavior will hopefully allow you to only see the resource applications which are relevant to you, rather than populating your screen with all possible resources.
Finally, moving forward we are looking to take a step back from having to statically register permissions that clients require to call resource applications. Instead we will be pushing a new Incremental and Dynamic Consent framework. You will note that here that we are taking a dependency on the scope names, rather than the ObjectID GUIDs of those permissions as we did in the past. But still, I agree with you in general that the discoverability of the scopes that resources expose is very heavily dependent their own public documentation. I imagine in the future there might be an endpoint which exposes all the scopes available on a particular resource, but I know of no such work to do this in the near future.
Let me know if this helps!

Get all domains for a tenant through REST API

I want to know if there is a way to retrieve the registered domain(s) for a tenant through REST API for Sharepoint/Office365.
Consider this scenario;
I have a tenant named abc.pqr and url for the "my" site(OneDrive) is abc-my.sharepoint.com.
Now when I create a user for this tenant, the UI panel gives the option to select a domain for this account. Available options are;
1) #abc.pqr
2) #abc.onmicrosoft.com
Now, the problem is, if I have a user of this sort >>> testUser#abc.onmicrosoft.com, how do I findout the registered domain for this tenant? Which in my case is abc.pqr.
Is there a way to find this through REST API?
Sounds like what you want to know is the list of verified domains in your Azure Active Directory tenant. (Azure AD is the directory service behind Office 365 and other Microsoft online services.)
The Azure AD Graph API—AAD's REST API—can provide this for you. In your case, the GET request you would want to make is:
https://graph.windows.net/abc.onmicrosoft.com/tenantDetails
Note: you can use either the tenant ID or any verified domain of the tenant instead of abc.onmicrosoft.com. The tenant ID can be obtained from the tid claim in the access token.
The JSON response will include something like this:
"verifiedDomains": [
{
"capabilities": "None",
"default": true,
"id": "0007ABE0983098",
"initial": false,
"name": "abc.pqr",
"type": "Managed"
},
{
"capabilities": "Email, OfficeCommunicationsOnline",
"default": false,
"id": "0007ABE0983098",
"initial": true,
"name": "abc.onmicrosoft.com",
"type": "Managed"
}
]
(There's a useful Quickstart for the Azure AD Graph API that shows how to start playing around with AAD Graph API, and the GraphExplorer.)
If you're using .NET, there is a full sample at https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet. (More samples for other languages and platforms at https://github.com/AzureADSamples.)

Resources