Unable to get Access token in microsoft Oauth 2.0 - azure-active-directory

I am developing the integration for Microsoft One Note with third party application using OAuth 2.0
And I have successfully authorised my Microsoft O365 account and provided my consent, but unable to get access token after the successful authorisation.
Error Message looks like : Invalid client secret is provided.
Timestamp: 2019-03-19 07:52:28Z
One Note Documentation : enterprise notebooks on Office 365 integration

As the document states format should be like below
POST https://login.live.com/oauth20_token.srf
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id={client-id} // Your Azure portal register application ID
&client_secret={client-secret} // Key Of same registered application
&code={code}
&redirect_uri={redirect-uri}
You are providing invalid client secret key while you are requesting API
See the screen shot below and make sure you are providing right one
Note:
Check your EXPIRES of key as never expires
Update:
In your case you have to follow two step to get your access token
First need to get authorization code
Request for token with that authorization code
Authorization code request sample
Token Request sample with authorization code

Related

Graph API Not able to access "https://graph.microsoft.com/v1.0/me/messages" endpoint

I am trying to access "https://graph.microsoft.com/v1.0/me/messages" API by JAVA SDK provided by Microsoft.
I am using the below code.
final AuthorizationCodeCredential authCodeCredential = new AuthorizationCodeCredentialBuilder()
.clientId("b****08f-*****-4d49-****-cba7d9a****c")
.clientSecret("8***7Q~GW0N******Y_N*****Zi******")
.authorizationCode("0.AVUAoIQSV...")
.redirectUrl("http://localhost/auth-responses")
.build();
Now it is giving me error like "The tenant for tenant guid '571284a0---****-a94eea6c6b3f' does not exist."
I tried the Same thing by postman, here I tried to get token by below end point.
"https://login.microsoftonline.com/common/oauth2/token"
after getting the token I am using it in "https://graph.microsoft.com/v1.0/me/messages" as Bearer Token. Still, I am getting the same issue.
But the token I am receiving in every case is not same as graph explorer Access Token
If I copy Graph Explorer Access Token and use it in postman then it gives me the desired result.
I am using a personal account for all of this process which ends with "#outlook.com".
I want to know why I am getting different access tokens than graph explorer access tokens and why that access token is not able to access the endpoints.
I have tested in my environment.
The access token generated from the Graph Explorer will be different from the access token generated from the Postman. This is because, the access token generated from graph explorer uses only the user credentials. The access token generated from postman uses client id and the client secret along with user credentials.
If the app registration supports Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox), then only you can use personal account to generate the access token and use it to call the request for https://graph.microsoft.com/v1.0/me/messages only if the app registration have Microsoft Graph mail.read delegated permissions.
Paste the below URL in the browser. The code will be generated. Copy the code.
https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize?
client_id=app-client-id
&response_type=code
&response_mode=query
&scope=mail.read
Make the below POST request in the postman to generate the access token :
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
Headers :
Content-Type: application/x-www-form-urlencoded
Body :
client_id: App Client ID
grant_type: authorization_code
scope: user.read%20mail.read
code: Code received in the first step
client_secret: Client Secret Generated in the App
Copy the Access token and make the below get request in the postman to read the messages :
GET https://graph.microsoft.com/v1.0/me/messages
Headers:
Authorization : Bearer access-token

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.

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.

What happens during a AcquireTokenAsync call using the client certificate?

In Azure AD, when we make a call such as AuthenticationContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(_clientId, _cert)) it is not clear what exactly happens.
What part of the certificate gets exchanged if any?
Is there a challenge/response taking place?
Is the private key needed on the client as a part of this?
There are two ways you could go about finding the answer to you questions. One would be to look at the Microsoft Active Directory Authentication Library (ADAL) for .NET source code on GitHub, since this is open-source. The other (which we'll do here) is to looking at the network request that AcquireTokenAsync(String, ClientAssertion) generates, and work backwards from there.
Using Fiddler (or any other traffic analyzer), we can see something like the following (formatted for readability):
POST https://login.microsoftonline.com/{tenant-id}/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&resource=https%3A%2F%2Fgraph.windows.net
&client_id={app-id}
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ
Breaking it down:
grant_type=client_credentials tells us this is a token request using the OAuth 2.0 Client Credentials Grant flow.
resource=https%3A%2F%2Fgraph.windows.net gives the URI of the resource the client is requesting an access token for. In this case, it's for the Azure AD Graph API.
client_id={app-id} is the client identifier. In Azure AD, this is the app ID of the application that was registered.
The presence of client_assertion_type and client_assertion are indicative that the client is using an assertion to authenticate:
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer says that client assertion being used is a signed JSON Web Token (JWT).
client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ is the aforementioned signed JWT token. The authorization server (e.g. Azure AD) will validate the contents, and check that the token was indeed signed by the certificate authorized for the client in question.
So, what ADAL does is:
Construct a token with a set of claims about the client (your app)
Use your certificate's private key to generate a cryptographic signature of those claims
Bundle that up into a signed JWT
Make an appropriately formed token request to the authority
During AcquireTokenAsync, only the certificate's thumbprint is provided (it's included in the JWT header to help the authorization server look up the corresponding public key). The JWT's signature is what proves that the client is in possession of the private key. However, before AcquireTokenAsync(String, ClientAssertion) can be used successfully, the client owner (i.e. you) needs to have provided Azure AD with the certificate's public key.
There is no challenge/response taking place here. The token is obtained in a single request, initiated by the client.
For a lot more detail, you can review the standards that this all implements:
RFC 6749: The OAuth 2.0 Authorization Framework
RFC 7521: Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7519: JSON Web Token (JWT)
(Note that ADAL has a cache. Everything I described above will take place only if ADAL does not find a valid access token in the token cache. You can use AuthenticationContext.TokenCache.Clear() to clear the cache for experimentation.)

Resources