How to get data from Microsoft Bing Ads API - azure-active-directory

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.

Related

Azure AD B2C. ROPC flow error The application associated with client id has no registered redirect URIs

The application associated with client id 09ac92da-a796-4cd9-973b-c97756____ has no registered redirect URIs
Description
I followed the steps described in https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-ropc?tabs=applications.
When attempting to obtain the token in Postman using ROPC I'm getting
{
"error": "invalid_request",
"error_description": "AADB2C90007: The application associated with client id '09ac92da-a796-4cd9-973b-c97756____' has no registered redirect URIs.\r\nCorrelation ID: e85003c3-cfd5-43ad-a74b-efa5c1ea6525\r\nTimestamp: 2019-12-06 19:47:42Z\r\n"
}
I should not be asked for a redirect URIs.
My POST is as follows:
URL: ''https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/oauth2/v2.0/token?p=B2C_1_ROPC_Auth"
username: some_username_of_a_user
password: its-password
grant_type: password
scope: openid offline_access 09ac92da-a796-4cd9-973b-c97756____
client_id: 09ac92da-a796-4cd9-973b-c97756____
response-type: token id_token
I didn't reproduce your issue by following this document. Here are the main steps for your reference.
1.Create a resource owner user flow
2.Register an application(It is an application under Azure AD B2C, not Azure AD)
3.Test the user flow
This error generally occurs because you still need to configure some application claims in the b2c directory user flow to allow complete access to the application.
You need to make sure that the right versions of the authentication are in the reply url (likely extension v2.0) and that the reply URL is configured in the application and in the code.
Please look to the documentation for the reply URL schema that you would need to follow: https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=applications#register-a-web-application
If you still run into this issue let me know and I can reach out to the correct product team contacts, as sometimes this can happen due to breaking changes on our end.

How to solve "NoPermissionsInAccessToken" returned by Microsoft Graph when reading calendar or sending mail

Within our department we have a Classic ASP website that has been using our corporate Google accounts for authentication and to insert events into our Google Calendars. The organisation has just switched from Google to Office 365 and I'm trying to switch the code to use Outlook instead - with no success.
I can use the access token to GET https://graph.microsoft.com/v1.0/me and see the basic profile, but if I try to read calendar events or send an e-mail I see the message:
"error": {
"code": "NoPermissionsInAccessToken",
"message": "The token contains no permissions, or permissions can not be understood."
I created an Azure account with my personal Microsoft account and added an application. I added my colleagues and my corporate account as guest users. I set the permissions required and did the admin consent thing:
I then followed the steps on this page.
I first visit https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize, including the following query items:
client_id={client id}
response_type=code
redirect_uri={our URL}
response_mode=query
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={number}
This returns a "code", which I send to https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/token, including:
grant_type=authorization_code
client_secret={client secret}
client_id={client id}
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={same number as above}
redirect_uri={same URL as above}
code={code returned from /authorize}
This returns the id, access and refresh tokens. If I decode the access token using https://jwt.ms/, it seems to contain the appropriate audience and scope:
"aud": "https://graph.microsoft.com"
"scp": "Calendars.ReadWrite email Mail.Send openid profile User.Read"
...although I notice that there is no "roles" entry, which I see in some of the documentation. Is that an issue?
I then send the access token to https://graph.microsoft.com/v1.0/me with the following headers:
"Authorization", "Bearer {access token}"
"Host", "graph.microsoft.com"
"Content-Type", "application/json"
"Prefer", "outlook.timezone Europe/London"
That will return my e-mail address, etc., but if I change the URL to anything else, such as /me/photo/$value, /me/calendar/events, or try to send an e-mail I'm told that there are no permissions in the token.
I see that there are other similar questions, but they are mostly for the client_credentials flow (I'm not sure that makes any difference), and none of the answers has helped me resolve my problem.
Can someone please let me know if I've obviously missed anything - or I'm going about this in the wrong way to access Graph data on the client side? It seemed so straightforward with Google, but I'm finding the Microsoft documentation and examples a bit less detailed.
Adding guest users is meaningless.
What you have done is Admin consent for the Azure AD with your personal Microsoft account.
What you actually need to do is Admin consent for the target Azure AD/ O365 tenant.
Construct a consent link as following:
https://login.windows.net/{tenant ID of the target Azure AD}/oauth2/authorize?response_type=id_token&client_id={client ID}&redirect_uri={reply url}&response_mode=form_post&nonce=a4014117-28aa-47ec-abfb-f377be1d3cf5&resource=https://graph.microsoft.com&prompt=admin_consent
Access it in a browser and log in with an admin account of target Azure AD.
Another issue is that you are using Get access on behalf of a user. So you have to assign Delegated permissions rather than Application permissions in the Azure AD app.

Azure client credentials grant oath not working in hybrid setup for Graph Mail API access

In hybrid setup if client credentials grant type is used to get token and if that token is used to get on-prem user messages (https://graph.microsoft.com/v1.0/users('onpremuser#onpremdomain.com')/messages/) using graph api it fails by providing UnknownError.
When debugged on IIS logs error shown was "This token profile 'V1S2SAppOnly' is not applicable for the current protocol." error_category="invalid_token".
However if authorization code grant or resource owner password credential (ROPC) grant if used to obtain token , we were able to get messages of on prem user using graph API.
Have attached screenshot of token for both. How to make client credentials grant work for on-prem user messages access using graph API (in hybrid setup) ?
Update
Update i went and edited web.config of rest in Exchange server to have V1S2SAppOnly in profiles. After that previous error is gone and new error is seen.
Bearer+client_id="00000002-0000-0ff1-ce00-000000000000",+trusted_issuers="00000001-0000-0000-c000-000000000000#ea6064aa-d6fc-48d3-abb8-1728e1f39e0b",+token_types="app_asserted_user_v1+service_asserted_app_v1",+error="invalid_token" 2000008;reason="The+token+should+have+valid+permissions+or+linked+account+associated+with+partner+application+'00000003-0000-0000-c000-000000000000'.";error_category="invalid_grant"
I think the problem is with the aud claim, i.e. the audience for token.
For the first token that you have shared
aud value is 00000002-0000-0000-c000-000000000000. This is the resource Id for Azure AD Graph API and not Microsoft Graph API. For Microsoft Graph API, you should be using https://graph.microsoft.com or Id 00000003-0000-0000-c000-000000000000
this token is probably the one where you used client credentials grant, as there isn't any user claim
For the second token that you have shared
aud value is https://graph.microsoft.com which is correct
this token is acquired in context of a user name anoop so I guess this is the one which is working for you.
What you want is:
Application with Client credentials => Graph API => Local Exchange.
This scenario isn't supported out-of-the-box, but you can however tell your local exchange server to accept those tokens. See this answer https://stackoverflow.com/a/56131954/639153
In a nutshell, you need to change the authentication config of your front-end exchange servers to accept client credentials from the graph api. By default only delegated credentials are supported, and these settings are not documented on the exchange side.
Warning, we tested these settings, and it's working but not supported by Microsoft
This is the blog where I've found the answer to your question. https://blog.thenetw.org/2019/05/13/using-client_credentials-with-microsoft-graph-in-hybrid-exchange-setup/

Delete groups in Microsoft Graph API in C#

I get an authorization 401 error code when I try to delete a Group from the API in C# but if I try it in postman it succeeds. Feels kinda weird because I run the same command but it doesn't work...
The problem I think I have is that to DELETE a group in Office 365 I need to login to my account and that the application can't makes this action.
I gave all Group.ReadWrite.All access and all other permissions for the application. So I think I need to pass my Login credentials for Azure AD or am I incorrect.
Request :
StatusCode: 401,
ReasonPhrase: 'Unauthorized',
Version: 1.1,
Content: System.Net.Http.NoWriteNoSeekStreamContent,
Headers:
EDIT
I tried to not use my GetAccessToken() and use the token I got when using OAUTH 2.0 verification in Postman. If I took that bearer token I had no problem running my script and using DELETE.
So my question what the difference of using ADAL in C# code and the call that Postman Auth2.0. When using Postman I get a login page where I login to my Azure account, can I replicate this in code? For the authentication in C# I use this example.
NEW EDIT
As one wrote in the chat, I checked the access token and what roles I had on a website.
roles: [
"EduRoster.Read.All",
"Mail.ReadWrite",
"User.ReadWrite.All",
"Calendars.Read",
"People.Read.All",
"Group.Read.All",
"Directory.ReadWrite.All",
"MailboxSettings.Read",
"Contacts.ReadWrite",
"Group.ReadWrite.All",
"Notes.Read.All",
"Directory.Read.All",
"User.Read.All",
"Mail.Read",
"Calendars.ReadWrite",
"Mail.Send",
"MailboxSettings.ReadWrite",
"Contacts.Read",
"Member.Read.Hidden",
"Notes.ReadWrite.All"]
Some clarification: If you have a token and it doesn't have the necessary claims/permissions to make the API call you are trying, you'll should get a 403 Forbidden. If the token is missing in the API request or malformed, you'll get a 401 Unauthorized. Please see https://developer.microsoft.com/en-us/graph/docs/concepts/errors.
Are you making direct HTTP REST calls to Graph, or are you using the client library? I suggest that you look at some of our samples to get started for examples of token acquisition together with calls to Microsoft Graph. Try https://github.com/microsoftgraph/console-csharp-snippets-sample (uses a .Net client library) or https://github.com/microsoftgraph/aspnet-connect-rest-sample (uses direct HTTP REST calls).
Also are you acquiring a token in the context of a (signed-in) user, or in the context of the application (no signed in user)? If the former, you need to request a "delegated" permission. If the latter, you need to request an "application" permission. Please see these concepts: https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user and https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
Hope this helps,
You're on the right track.
The Delete Group method support both Delegated (Authorization Code or Implicit OAUTH grants) and Application (Client Credentials OAUTH grant) models. Both Delegated and Application flows require the Group.ReadWrite.All scope.
The reason you're getting a 401 Unauthorized error is that your application hasn't received Admin Consent for the tenant you're connected too. When using Client Credentials there is no User to authenticate so before your application can interact with the tenant, an Admin must first explicitly authorize your application and the scopes you're requesting.
You can find a walk through at v2 Endpoint and Admin Consent.

Postman - how to obtain Azure Active Directory token using sign in form?

Is is possible to obtain an AAD token in Postman by letting the user to Sign In using the standard AAD sign in form?
I know how to obtain token using the request to AAD (grant_type = client_credentials) but such a token does not have a UPN (user identity).
I would like to somehow type in my credentials in Postman and get the token. So it is a manual interaction, the user(me) needs to manually sign in - the same way how ie. Visual Studio verifies your identity.
Postman now offers the ability to "Authorize using browser." You'll need to make changes to your AAD application to support it in addition to configuring Postman.
Configure your AAD application
Add a redirect URI to your AAD application for Postman to receive the authorization code. In the AAD Portal, navigate to your app registration, then to the "Authentication" tab, then add https://oauth.pstmn.io/v1/callback as a new redirect URI. This URI was provided by Postman when you check the ✅ Authorize using browser box (below) and is also documented on their website.
Configure Postman
You can set this up under "Authorization" for a single request, a folder of requests, or a Collection. Open the "Authorization" tab and select OAuth 2.0. Under the "Configure New Token" section, enter the following information:
Token Name: anything you want. I chose the name of the AAD application.
Grant Type: Authorization Code (With PKCE)
Callback URL: check the ✅ Authorize using browser box
Auth URL: copy this from the AAD portal under Overview > Endpoints (on top bar) > OAuth 2.0 authorization endpoint (v2). Mine looks like https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize
Access token URL: copy this from the AAD portal under Overview > Endpoints (on top bar) > OAuth 2.0 token endpoint (v2). Mine looks like https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token
Client ID: copy this from the AAD portal under Overview. It's also commonly referred to as an "Application ID" and is a GUID.
Client Secret: leave blank (not used by this grant type)
Code Challenge Method: SHA-256
Code Verifier: leave blank or provide your own
Scope: the scopes you're requesting in your token, separated by spaces
State: leave blank or provide a value such as a random GUID.
Client Authentication: Send as Basic Auth Header (not used by this grant type)
Refer to Postman's documentation on OAuth 2.0 options for more information.
Get a token
Click Get New Access Token to open the auth flow in your machine's default web browser. After authentication, it should redirect back to the Postman application and a new token will be created with the name you provided earlier for "Token Name." Select "Use Token" in the top-right corner of the popup to copy it into your current token. If the token expires and your requests start failing authorization (probably a 401 or 403 error), you can revisit this tab and get a new access token.
Occasionally, you may want to visit Current Token > Access Token > Manage Tokens > Delete > Expired tokens, otherwise you'll be inundated with nearly-identical tokens.
Postman cannot popup the sign in page as it only does HTTP requests. As you stated, it can do confidential client flows.
What you could do is hand-construct an auth request, sign in, and grab the auth code. Then take that auth code and drop it into the Postman authorization form, and let it hit the Azure AD token endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/token
The Azure AD protocol referene will be super helpful for you.
I think if you're wanting to quickly generate Access Tokens your best bet is to pick a framework/language and build a lightweight app that gets and logs tokens. Azure AD has a Python Flask sample for the v2 endpoint that takes 5 minutes to setup and could be converted to printing out access tokens. If you want to use v1, you can checkout the list of samples at the Azure AD developer guide.

Resources