13

I am trying to develop a simple background app to connect to my onedrive account (work) and regularly download some files.

I followed this tutorial https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds

I have registered the app here https://apps.dev.microsoft.com/portal/register-app I have written down the client_id and client_secret

To get an access token I make a POST request to

https://login.microsoftonline.com/common/oauth2/v2.0/token with the following form encoded data

{
    'client_id': 'clientid here',
    'client_secret': 'secret is here',
    'scope': 'https://graph.microsoft.com/.default',
    'grant_type': 'client_credentials',
}

I get back an access_token

{'ext_expires_in': 0,
 'token_type': 'Bearer',
 'expires_in': 3600,
 'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciO---SHORTENED FOR BREVITY'}

Next I make a GET request (with Bearer header properly set) to https://graph.microsoft.com/v1.0/me

and get this eror response (which I get for any endpoint fwiw)

{
  "error": {
    "code": "BadRequest",
    "message": "Current authenticated context is not valid for this request",
    "innerError": {
      "request-id": "91059f7d-c798-42a1-b3f7-2487f094486b",
      "date": "2017-08-05T12:40:33"
    }
  }
}

I have these permissions configured in the app setting permissions

Any ideas what might be wrong?

Cœur
  • 37,241
  • 25
  • 195
  • 267
redacted
  • 3,789
  • 6
  • 25
  • 38

3 Answers3

13

I'll file a bug to improve this awful error message. The problem is that you are making a request using application permissions (client_credentials flow) - where there is no signed-in user context. Your request is to /me, and /me is basically an alias for the signed-in user - and in this case there isn't one!

You should try a call to https://graph.microsoft.com/v1.0/users instead. But, before you do that. In the app registration portal, you've selected delegated permissions, but you are calling with application permissions. You should remove the delegated permissions, and select the appropriate application permissions - to call users, select User.Read.All for example. Then make sure to consent/reconsent your app by going to the /adminconsent endpoint.

Please also read more on permissions and delegated and application permissions here: https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference

Hope this helps,

Dan Kershaw - MSFT
  • 5,833
  • 1
  • 14
  • 23
  • Dan, thank you! I've read more about OAuth2 and I see the issue here. Are the only supported flows the `client_credentials` and `authorization_code`? For my purpose I'd prefer to use the delegated permissions as I really only need access to the files the user can see, I don't need (and don't want) to access all of the Organization's files. Is the only way to do this to use the `authorization_code` which involves using `refresh_tokens`? Is there a way to get some kind of long-lived `refresh_token` or use the `grant_type=password`? – redacted Aug 08 '17 at 09:04
  • 2
    Please follow the guidance here: https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user for the authorization code flow and hadling refresh tokens which are long-lived. Please do not use the password flow - there are very specific scenarios for this flow and it comes with a bunch of serious disadvantages - please see http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/. – Dan Kershaw - MSFT Aug 08 '17 at 20:50
  • @RobinNemeth Hi are you able to solve this issue ? I got exactly same issue with delegated permissions. mine is a backend app and I dont want popup a login form for user to authorize. The grant_type=password doesn't work for me for I keep getting Invalid password error when calling ../token api;. – daniel Sep 26 '18 at 00:11
  • @DanKershaw-MSFT Hi Dan, according to the guidance we need to redirect user to endpoint /authorize which is basiclly a login page. Does this mean we can not skip this user action ? What if I want to fetch token with a backend app without user presence ? – daniel Sep 26 '18 at 00:16
  • @daniel you need to go through the consent screen and approve it at least once. After you go through the user consent, you get a refresh token that is valid for couple of days. After each exchange of `refresh_token` for `access_token` you get a new `refresh_token` which, when saved, you can use for further requests. I think you can continue to do this for at least 90 days so you don't need to do it too often – redacted Sep 26 '18 at 08:17
  • Thanks @RobinNemeth. Did you only use delegated permission ? if so what grant type do you use to get token ? – daniel Sep 27 '18 at 00:25
  • 1
    https://graph.microsoft.com/v1.0/users` resulted in a `401 Unauthorized` response: { "error": { "code": "Authorization_IdentityNotFound", "message": "The identity of the calling application (truncated...) – Kiran Reddy Feb 07 '19 at 07:54
  • I am getting the same error "code": "Authorization_IdentityNotFound",\r\n "message": "The identity of the calling application could not be established." – thedudecodes Mar 28 '19 at 10:53
  • @daniel were you able to resolve this issue? – DevOps QA Nov 08 '22 at 00:58
1

i used https://graph.microsoft.com/v1.0/users/{{Emailid}}/messages to get all the messages in my inbox

Abhijeet Sinha
  • 161
  • 2
  • 13
0

In clientCredential flow you are accessing as an with Client secret or with client certificate . So Graph API no linger understands who is me. So you need use https://graph.microsoft.com/v1.0/users/<Your_userId> or https://graph.microsoft.com/v1.0/users/<your_userprincipalname>.

eg.https://graph.microsoft.com/v1.0/users/1sd1353as.. or eg.https://graph.microsoft.com/v1.0/users/John_doe@contso.com

Reference: https://learn.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http

Sonali Das
  • 943
  • 1
  • 7
  • 24