HTTP/1.1 403 Forbidden while create upload session - azure-active-directory

I am trying to upload a file to Sharepoint. I Got the Accesstoken based on the client id and tenant id given by the application and able to do it.
'client_id='||'xxxx'||'&scope='||'https%3A%2F%2Fgraph.microsoft.com%2F.default'||'&client_secret='||'xxxxxx'||'&grant_type='||'client_credentials'
Token as follows :
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Based on the token i am trying to create an upload session and it is saying http1.1 403 forbidden. I have the known site id and Drive (Item id).
HTTPResponseHeader X-Original-HTTP-Status-Line:CHARACTER:HTTP/1.1 403
Forbidden X-Original-HTTP-Status-Code:INTEGER:403 Cache-Control:CHARACTER:private
Content-Type:CHARACTER:application/json request-id:CHARACTER:1f6e2c51-5061-41c0-be0d-ee38a2c2a533
client-request-id:CHARACTER:1f6e2c51-5061-41c0-be0d-ee38a2c2a533 x-ms-ags-
diagnostic:CHARACTER:{"ServerInfo":{"DataCenter":"South Central US","Slice":"SliceC","Ring":"3","ScaleUnit":"000","RoleInstance":"AGSFE_IN_11"}}
Strict-Transport-Security:CHARACTER:max-age=31536000
Date:CHARACTER:Fri, 19 Jun 2020 17:23:53 GMT Content-Length:CHARACTER:256
Application had given permissions to Sites.readwrite.All provided admin consent as well. Any help is Appreciated.

So there's a couple of things here:
To use the Microsoft Graph APIs to create an upload session to write a file to SharePoint using the site/library as a drive with an app only permission (client_credentials) you need to request the at least the Sites.ReadWriteAll scope for the Microsoft Graph resource https://graph.microsoft.com: https://learn.microsoft.com/en-us/graph/api/driveitem-createuploadsession?view=graph-rest-1.0
Instead of requesting the https://graph.microsoft.com/.default scope try using 'https://graph.microsoft.com/Sites.ReadWriteAll`

Related

How to get data from Microsoft Bing Ads API

I'm trying to get Bing ads spends from my firm. According to the Microsoft documentation, I understood that it's mandatory to use Microsoft Azure portal, get developer_token, client_id, tenant_id, client_secret, and access/refresh token to download the csv files with the data I want.
So, this is what I did:
I've received an invitation from my firm to Microsoft advertising onto this email adress:
abc#myfirm.fr, and I've generated my developer token.
With this email address, I've created a web application onto Microsoft Azure portal, which allow all king of users. Getting client_id, tenant_id, and generated a client_secret.
The redirect URL that I have chosen is http://localhost (according to the documentation but not sure this is the good URL to choose).
With Postman, I have tried with this endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
and the params (previously obtained) needed for the OAuth 2.0 authentication to get my access token. Without success.
The issue is here.
When I request the access token, a new browser window opens, and asks for an email address on which to authenticate. I'm using my email address abc#myfirm.fr and I received authentication completed onto Postman but into the response body I have access_token: invalid.
The role of my account is super admin.
So I'm trying to authenticate with a professional Microsoft Azure Account and this time I received into the browser Invalid redirect url.
I have also tried to start all over again with different email address, like my personal email address, or with the email address of the creator of the Microsoft Advertising account, and I get the error contact your system Admin into the browser.
I have also tried with the Python SDK project given in the documentation, with the error message.
I must have forgotten or misunderstood something.
Should we use the same email address (or same account) on Microsoft Advertising, on Microsoft Azure, and when obtaining the access token?
Do you have to pay and take an Azure subscription? (Already done but without success)
Thanks in advance, sorry for my English.
EDIT:
Thank for ypur reply. The full request is: https://login.microsoftonline.com/common/oauth2/v2.0/authorize with the following params:
-type: OAuth 2.0
-Header Prefix: Bearer
-Grant Type: Authorization Code
-Callback URL: https://localhost
-Auth URL: https://login.microsoftonline.com/{my-tenant_id}/oauth2/v2.0/authorize
-Access Token URL: https://login.microsoftonline.com/{my-tenant_id}/oauth2/v2.0/token
-my client id
-my client secret
-scope: https://ads.microsoft.com/ads.manage OR also testing with https://graph.microsoft.com/User.Read
-State: None
-Client authentication: send client credentials in body
Give me an access_token but when I click on use token and send the request, I'm not getting an refresh token
Once a user provides consent, you can get an access token and act on behalf of the user.
So when the browser session starts, you should enter your Microsoft Advertising credentials.
Remember to set scope=https://ads.microsoft.com/ads.manage in the request for acquiring the authorization code.
If you prefer to automate this process, you can refer to this script and steps to obtain an access token.

Unable to read/write contacts to a user mailbox

In Microsoft 365, we’re able to create a personal contact but we can’t view the contacts of users, let alone add personal contacts to users mailboxes. We keep getting an ErrorAccessDenied message in the output.
Can anyone please advise on how we can get this resolved?
Microsoft Graph Explorer uses user token (delegated permission) to access the contacts data.
It only supports POST /me/contacts.
To access others' contacts, we need to implement Get access without a user which uses client credentials flow.
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
In this way you can get an application token (application permission). You can use it to access other users' contacts.
You can use Postman to have a test. Microsoft Graph explorer doesn't support client credentials flow.

Error "invalid_client" when trying to get a token from Microsoft API

I'm trying to develop a drive solution (Onedrive) in a windev program.
I created an application in Microsoft Azure and created a secret key.
When doing the first request https://login.live.com/oauth20_authorize.srf?client_id={client_id}&scope={scope} &response_type=code&redirect_uri={redirect_uri} I'm redirected on the connection page.
Once I'm connected I get a code back as https://login.live.com/oauth20_authorize.srf?code={code}.
But when I ask for a token posting this request : POST https://login.live.com/oauth20_token.srf Content-Type: application/x-www-form-urlencoded client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret} &code={code}&grant_type=authorization_code
I get this back
{ "error":"invalid_client", "error_description":"The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https:\/\/go.microsoft.com\/fwlink\/?linkid=2083908.", "correlation_id":"471e800c-69b4-43c6-a03f-a1f7e9512e6b" }
Thank you for your help.
This error means you are using a Microsoft Account to login your client app, but it is not enabled for that.
To change the setting for an existing AD App, navigate to the Manifest blade of it in the portal, find the signInAudience attribute, set it with AzureADandPersonalMicrosoftAccount or PersonalMicrosoftAccount.

Azure Log Analytics API permissions on west-us2 region

We try to create an AAD service principal for retrieving data from out Log Analytics workspace.
Our AAD region is located in Germany
Log Analytics is located in North Europe
When attempting to create API permissions, the address to the API itself is mentioning westus2.api.loganalytics.io (west US region) which is a no go for our company data privacy.
Is there any reason of this default and not editable settings ? Is there any way to overcome it ?
Well, if so, you could get the token for ARM API endpoint, then call the ARM API.
In this way, no need to add the API permission for your AD App, just make sure your AD App has an RBAC role e.g. Contributor, Log Analytics Reader in the Access control (IAM) of your workspace, if not, follow this doc to add it.
Then use the client credential flow to get the token.
POST /YOUR_AAD_TENANT/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&redirect_uri=YOUR_REDIRECT_URI
&resource=https://management.azure.com/
&client_secret=YOUR_CLIENT_SECRET
After getting the token, use it to call the api like the sample below.
GET https://management.azure.com/subscriptions/6c3ac85e-59d5-4e5d-90eb-27979f57cb16/resourceGroups/demo/providers/Microsoft.OperationalInsights/workspaces/demo-ws/api/query
Authorization: Bearer <access_token>
Prefer: response-v1=true
{
"query": "AzureActivity | limit 10"
}
For more details, refer to this link.

Can service/daemon app use 'common' instead of 'tenant-id' when obtaining token from Azure AD v2.0 endpoint

I am developing a daemon app that can perform actions on user inboxes in multiple tenants. Once an admin from a tenant gives the app the required permissions, it should be able to access users inboxes in that tenant. I am doing the following now.
Get consent from admin
https://login.microsoftonline.com/common/adminconsent?client_id={client-id}&redirect_uri=https%3A%2F%2Fredirect.test.com
Global Admin from a tenant (e.g. myutils.onmcirosoft.com) gives required permission.
Get access token by using common instead of tenant-id
curl -X POST _https://login.microsoftonline.com/common/oauth2/v2.0/token --data "grant_type=client_credentials&client_id={client-id}&client_secret={clientsecret}&scope=https://graph.microsoft.com/.default
It gives a access token.
Access messages of admin#myutils.onmicrosoft.com using the token obtained in step 3.
curl -X GET -H "Authorization: Bearer <token>" https://graph.microsoft.com/v1.0/users/admin#myutils.onmicrosoft.com/messages
Above curl request gives the following 404 response:
HTTP/1.1 404 Not Found
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/plain
request-id: e602ada7-6efd-4e18-a979-63c02b9f3c76
client-request-id: e602ada7-6efd-4e18-a979-63c02b9f3c76
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"West US","Slice":"SliceB","ScaleUnit":"000","Host":"AGSFE_IN_22","ADSiteName":"WST"}}
Duration: 1537.3097
Date: Tue, 19 Sep 2017 09:31:08 GMT
In step 3 if I replace common with tenant-id of myutils.onmicrosoft.com it is working.
Is common supported with Azure AD v2.0 endpoint? This link says common is not supported for v1 endpoint. Is it the same for v2.0 endpoint as well?
Just to expand on Nan Yo's answer, the reason you need the tenant-id is due to Graph API itself being a multi-tenant.
Without a tenant-id, Graph would have no way of knowing which tenant to route your calls too. For example,/users returns a list of users but without a tenant-id there is no way to determine which tenant it should pull the users from.
When you use authorization_code or implicit grants, it uses the user's credentials to determine which tenant calls should be routed too. With client_credentials you don't have those credentials to pull those routing queues from.
You can however determine the tenant id during Admin Consent. Along with the admin_consent result, it also returns the tenant. For a multi-tenant service you would need to store that id to use when obtaining a token prior to making a call to Graph.
When using the client credentials flow in Azure AD V2.0, you need to specify the actual tenant that you want a token for. Otherwise , even you get an access token , you will find no application roles include in the access token . An access token will issued from one tenant and could access resource of that tenant , it is impossible to use one access token to query resources of multi tenants .
Please acquiring your token not from /common/oauth/v2.0/token endpoint , use /{tenent-id}/oauth2/v2.0/token endpoint with the tenant id .
Please click here for more details .

Resources