Unable to delete Sharepoint Online term store items programmatically - sharepoint

I'm trying to delete terms or term sets from the default taxonomy store in a C# application which authenticates with an Azure App. I've tried using certificate and app secret authentication as well as a user account context. Using the certificate/app secret, the authentication is successful and I can read terms but receive an error when I try to delete a term:
Microsoft.SharePoint.Client.ServerUnauthorizedAccessException: 'Access denied. You do not have permission to perform this action or access this resource.'
Tried this using both using CSOM and PnP Framework. The App has full read and write permissions for the SharePoint API and Graph API relating to SharePoint/Term Store.
Using user account, I get an error that the login/password could not be found. MFA is disabled for this account in 365 Admin, but it seems the web portal still asks for this to be set up when logging in via browser.
Using the MS Graph API and the same Azure App, I can also create terms, but Graph does not support deleting terms at the moment so this method cannot be used.

Related

What permissions are needed in azure AD portal for getting user data via sharepoint rest api

I wanted to use "_api/SP.UserProfiles.PeopleManager/GetMyProperties" this endpoint to fetch user details. While fetching data, I am getting below error message :
"value": "Access Denied: This application does not have the required permissions to access profile information."
I am not certain if that endpoint can be used to get user properties from Azure. It might be better to use Microsoft graph to achieve retrieving user properties if you are not working from within SharePoint directly.
If you are building your app with JavaScript you can use the package;
https://pnp.github.io/pnpjs/graph/users/#user-properties
Regarding the permissions required, refer to the article below, it describes how to setup your application on Azure and the necessary information you will use to connect to SharePoint via the App permissions you have configured on Azure.
The article describes how to read sites but, in your case, you will focus on assigning the app permission to read user info.
https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread

MSAL PublicClientApplicationBuilder with AzureAD external user cannot access SharePoint

We have a Windows Application using MSAL with PublicClientApplicationBuilder to access SharePoint with the delegated permissions of the logged on user.
When our code is used with a login of a user who was invited as an external user in another AzureAD and his user is added to the members of a SharePoint site collection, we get an access token which results in HTTP 401. Using a user from the other AzureAD directly to log in does work. It is just with external user, we fail to get access.
When the user logs into SharePoint in the browser, using his external user login, he can access the other tenants SharePoint. So his external user account has permissions on that site collection, but it works only in the browser, not from our MSAL client.
Some details:
We created the app registration as multi tenant app in our AzureAD with the needed read and write permissions from the SharePoint delegated permission list.
An admin of the other AzureAD consented the delegated permissions for all users and we did the same in our AzureAD. So no matter which user tries to login and use the app will find consented permissions.
We use this code to get a public client app:
var clientAppId = "our-app-clientID";
var redirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient";
_clientApp = PublicClientApplicationBuilder.Create(clientAppId)
.WithRedirectUri(redirectUri)
.WithLogging(Log, LogLevel.Verbose, false)
// .WithTenantId("we tried our and the other tenants ID")
.Build();
The commented line .WithTenantId was just added while we tried to find a solution.
We can see that it makes a difference for the token content. Without that line or with our tenantId we see the users "oid" is the objectId from the user in our AzureAD.
When we use the tenantId of the other AzureAD, we get the oid of the external user object in that other AzureAD.
So we had hopes that the latter call would succeed, but it fails as well, this time with HTTP 403. So the user token seems to get a bit further, but still not to the SharePoint site collection.
Any idea if this scenario is possible?
Would be nice, if possible and best if we would not have to call WithTenantId because otherwise we would some need to lookup the correct tenantId on the client machine - not sure where to get it from, except asking an admin from the other tenant and putting the value in some app config file or the Windows registry.
• The issue most probably according to your description suggests that the scopes might not be added correctly to the ‘Sharepoint API’ because since you are accessing the sharepoint site from a public client using MSAL authentication, the scopes/permissions to access the sharepoint site from a public client in Azure AD needs to be added and extended to service the requests from external user accounts also.
To do so, you need to add scopes/permissions to Sharepoint API through the Azure portal as when you are calling SharePoint APIs outside of the Microsoft Graph, you call ‘/_api/web/lists’ and it will retrieve all the lists. Thus, if your public client app performs this action using the Microsoft Graph API permissions then you will get an access denied error message as you are encountering HTTP 403 error.
• Thus, in your case, to access the sharepoint sites, you will need to add the scopes ‘AllSites.Read’ and ‘Sites.ReadWrite.All’ to the Sharepoint API for your public client app as the scope for ‘Sites.Read’ in the Microsoft Graph API isn’t enough for it. Also, ensure to add the ‘https://<domain>.sharepoint.com/AllSites.Write’ and ‘https://<yoursite>.sharepoint.com/Sites.ReadWrite.All’ scopes also to the Sharepoint API for that public client app.
To access the Sharepoint API through public client, you use AAD auth for which Microsoft recommends using a certificate rather than a secret. For more information regarding this, kindly use the below documentation link: -
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-authentication-flows#client-credentials
• Also, ensure that ‘https://microsoft.sharepoint-df.com/Sites.Search.All’ and ‘https://yourtenant.sharepoint.com/Sites.Search.All’ are also added as scope in your application as Sharepoint online site might reject the token because of invalid audience.
For more information regarding the scope modification, kindly refer the below link for more details: -
https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/400

OneDrive Personal Daemon Api Access

I have a Personal OneDrive Account Purchased (not Free Tier).
What am I trying to do ?
To write a Daemon in Python that will connect to OneDrive Personal Account Folders and upload / show contents.
What did I tried doing ?
I learned Microsoft Graph is the way to go to access all personal business accounts.
So I signed in with Azure (Free) Portal with my OneDrive Credentials myname#yandex.com , after signing in it created a Azure Default Directory with mynameyan...#onmicrosoft.com as principal user.
Followed Tutorial and created App under App Registration granted it all the Permissions and Also admin Consent through the portal and generated Client Secret and Downloaded the sample code from QuickStart under Portal->Azure Directory-> App Reg..
Ran it on my computer with just one change in the code. After getting the Access Token , I changed the Graph Endpoint to /me/drives/root and I got a "Tenant does not have SPO License" , also I noticed when I change the graph endpoint to /users it yields me mynameyan..#onmicrosoft.com as principal account name. When I expect myname#yandex.com
So in graph Explorer I tried and it yields me proper principal account name as myname#yandex.com also lists all the onedrive personal files as expected.
Problem ?
I cannot authenticate myself properly , since my application will be a Daemon I can't present myself a Login Page with redirect URLs so "Code Flow" type of Acquiring Authentication Token for Personal Accounts will not work for me as mentioned in the Tutorials.
Also if I forcefully query /me it says "Please use consumer endpoint" if I change the Authentication Endpoint it says invalid Client ID and Credentials (Because I think that onmicrosoft.com principal name cannot be used to query OneDrive Personal which belongs to myname#yandex.com )
What do I request ?
An idea of how would others implement this daemon with brief if not detailed steps of configuration in Azure and Code , if possible a Sample code and an Algorithm.
I am new bla bla....hehe , actually I am new to Azure and is also using OAuth First Time. Thanks in advance. I will edit the question if someone needs more information on this to help me.
You cannot use daemon to access personal account OneDrive files.
Daemon app will use Application permission (without user) to do the operation.
But based on the Microsoft Graph Get Files Permissions, Only Delegated permission is supported for personal Microsoft account. And Delegated Permission means app + user permission.
Currently you have to implement Get access on behalf of a user and use auth code flow to access personal account OneDrive files with Microsoft Graph API.

Having trouble getting Azure AD user's groups

I'm currently using node.js passport library to authenticate using the OIDC Strategy with an azure registered app using a client ID and secret.
http://login.microsoftonline.com/{org id}/v2.0/.well-known/openid-configuration
I am not having any trouble getting the user profile back of the person who logged in, but I am hitting a wall when trying to get the groups. In my app, I need to authorize the user based on their active directory groups. I am getting back this piece of json:
"_claim_names\":{\"groups\":\"src1\"},\"_claim_sources\":{\"src1\":{\"endpoint\":\"https://graph.windows.net/{org guid}/users/{user guid}/getMemberObjects\"}}
I'm not sure what I need to do using this to get the groups. I tried generating a bearer token, passing that in a header, and getting the groups but it says I am unauthorized using Postman. Do I need certain permissions in the app? Also why is it using graph.windows.net when I'm trying to use graph.microsoft.com?
Is there an easier way to do this once the user has logged in?
Overage indicator claim when user is member of many groups
The claim you're getting back as part of json shared in question is an overage indicator claim.
"_claim_names\":{\"groups\":\"src1\"},\"_claim_sources\":{\"src1\":{\"endpoint\":\"https://graph.windows.net/{org guid}/users/{user guid}/getMemberObjects\"}}
It means that the user is member of many groups and instead of including information about all the groups as part of token (which would make the token too big), you will need to query that information separately.
Read more about it here: Access Tokens Reference
How to get groups information?
Your application needs to make a separate call to Microsoft Graph API to get the groups information for user.
Relevant Microsoft Graph APIs
user: getMemberObjects
user: getMemberGroups
Check member groups
Permissions Required by your application
Each of the API links above mention the required delegated or application permissions that are required as part of documentation.
You will need to update your app registration in Azure AD to require the relevant permissions (and also go through Admin consent, in case the permission required needs admin consent)
Token to call Microsoft Graph API
You mention that you've tried generating a bearer token, passing that in a header, but you got Unauthorized error.
Once you're done with the permission changes for your application, acquire a token specifically for Microsoft Graph API from your application. The bearer token used to access your application may not directly work with Microsoft Graph API.
Also make sure you go through Admin consent in case any of the permissions require Admin consent. If it's a single tenant application, "grant permissions" directly from azure portal by an administrator should work, in case of multi-tenant app you can use the Admin consent endpoint.
Code Sample: Here is a quick tutorial for calling Microsoft Graph using Node.js.. you may find other good ones as well.
Azure AD Graph API (graph.windows.net) vs Microsoft Graph API (graph.microsoft.com)
You have a valid question about the endpoint.. "Also why is it using graph.windows.net when I'm trying to use graph.microsoft.com?"
General recommendation is to use the newer Microsoft Graph API, unless the functionality/information you're looking for isn't available with Microsoft Graph and only Azure AD Graph API can help. Read more about recommendation and comparison here: Microsoft Graph or Azure AD Graph
Since information about groups is available in v1 endpoint for Microsoft Graph already (not beta), you should make use of Microsoft Graph API.
Here are a couple of related SO posts: SO Post 1 and SO Post 2

SP Online REST API Issue when uses AZURE Access token

My requirement is described below.
User uploads the document through web-app and document saves in to shared location.
Application service (cron job or server code) , selects the documents and extracts the details.
Cron job send the details to SharePoint rest api which is protected by azure AD. (Oauth protocol)
I have a valid AZURE client ID and Secret ID which has application level access permission. I got access token by using AZURE client ID and Secret ID from AZURE AD with help of simple JAVA code but am getting following error when i call sharepoint online REST service using Oauth access token.
Error : {"error_description":"Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown."}
What does it mean? Can anyone help me resolve the issue ?
As SharePoint Online has strict safety standards, authentication for working with REST API consists of three steps:
1.Get the security token from Microsoft authentication portal.
2.Get the cookies from the SharePoint Online server.
3.Get the signature for requests to the SharePoint Online server.
More information is here:
http://www.wave-access.com/public_en/blog/2015/june/23/java-service-integration-with-sharepoint-online-via-rest-api.aspx
Access Office 365 from JAVA, we can use Office 365 SDKs for Java.
https://github.com/OfficeDev/Office-365-SDK-for-Java

Resources