Can't deploy an app to Intune store via graph API - DeviceManagementApps.ReadWrite.All is an invalid scope? - microsoft-graph-api

We want to enable uploading apps to the Intune store via an API.
I saw this example on GitHub, and want to do something similar in JS, so I've tried using the same REST calls.
The problem is, I can't seem to make the https://graph.microsoft.com/beta/deviceAppManagement/mobileApps request properly - I always get 401. When making the same request via the Graph API Explorer it works fine.
I tried fixing my permissions, and I'm kinda stuck getting the correct token.
I did the following steps with an admin account, on both the "common" and our own tennant:
Called the admin consent - https://login.microsoftonline.com/nativeflow.onmicrosoft.com/adminconsent?client_id=<ID>&redirect_uri=<URI>
Got authorization from the user - https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=<ID>&response_type=code&redirect_uri=<URI>&response_mode=query&scope=DeviceManagementApps.ReadWrite.All
POST request to get the actual token -
https://login.microsoftonline.com/nativeflow.onmicrosoft.com/oauth2/v2.0/token
with the following body:
client_id: <ID>
scope: https://graph.microsoft.com/.default
client_secret: <secret>
grant_type: client_credentials
requested_token_use: on_behalf_of
code: <The code I got in step 2>
I tried changing the scope in step 3 to https://graph.microsoft.com/DeviceManagementApps.ReadWrite.All or simply to DeviceManagementApps.ReadWrite.All, but it says that it's not a valid scope.
I got a token in step 3, but when I try calling the actual API I receive this error:
{
ErrorCode:"Forbidden",
Message:{
_version: 3,
Message: "An error has occurred - Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 - Activity ID: 7b5c3841-976d-4509-b946-f7fdabd047d7 - Url: https://fef.msub02.manage.microsoft.com/StatelessAppMetadataFEService/deviceAppManagement/mobileApps?api-version=5018-05-02",
CustomApiErrorPhrase: "",
RetryAfter: null,
ErrorSourceService: "",
HttpHeaders: {"WWW-Authenticate":"Bearer realm=urn:intune:service,f0f3c450-59bf-4f0d-b1b2-0ef84ddfe3c7"}
},
Target:null,
Details:null,
InnerError:null,
InstanceAnnotations:[]
}
So yeah, I'm pretty much stuck. Anyone have any experience with it? I've tried making the calls in Postman, curl and via code, but nothing works.
Cheers :)

You have a couple issues going on:
You're using the Authorization Code Grant workflow but requesting Client Credentials.
The scope Device.ReadWrite.All is an application scope, it is only applicable to Client Credentials. It isn't a valid Delegated scope so it will return an error when you attempt to authenticate a user (aka delegate) using Device.ReadWrite.All.
Your body is using key:value but it should be using standard form encoding (key=value).
To get this working, you need to request a token without a user. This is done by skipping your 2nd step and moving directly to retrieving a token (body line-breaks are only for readability):
POST https://login.microsoftonline.com/nativeflow.onmicrosoft.com/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={id}
&client_secret={secret}
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&grant_type=client_credentials

Related

Amazon Alexa Get Access token

I am writing a SmartHome skill and need an access token to post asyncrhonous notifications for a device (doorbell). The documentation is confusing - but from what I have infered - I am supposed to get my client_id and client_secret from the Alexa console, and get the Bearer Token during the initial skill connection/authorization, then request the access token (and refresh token) via OAuth. So I can get these three pieces of info, but then I try to do:
curl -vv X POST -H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' -d "\
grant_type=authorization_code\
&code=$CODE\
&client_id=$CLIENT_ID\
&client_secret=$CLIENT_SECRET" \
https://api.amazon.com/auth/o2/token
Where CODE came from the initial authorization request as:
"payload": {
"grant": {
"code": "<<REDACTED>>",
"type": "OAuth2.AuthorizationCode"
},
But this always gives me:
{"error_description":"The request has an invalid parameter : code","error":"invalid_grant"}
If I remove the code parameter it complains it's missing, and if I change the code to something invalid, the error changes from invalid_grant to invalid_request. So it understands the code - but doesn't like something about this whole flow.
(I know the client_id, client_secret and grant_types are valid, because when I change them to something deliberately erroneous, I get some expected error).
Any idea what I'm doing wrong??
The code can only be used once - whether it succeeds or not. So even if you use it and your request is botched or otherwise doesn't work - you cannot reuse it. The only was I was able to handle this was to disable the skill, re-enabled it, then snoop and use the new code given.

YouTube Authorization Code exchange fails with redirect_uri_mismatch

I'm trying to exchange an authorization code for access code, but I'm getting an error saying "redirect_uri_mismatch".
I waited ~8 hours just in case it needs to update, but no luck so far.
The redirect uri's are set correctly, as you can see from the image here.
Initial Front-End redirect/request:
GET => https://accounts.google.com/o/oauth2/v2/auth
?scope=https://www.googleapis.com/auth/youtube.readonly
&include_granted_scopes=true
&state=state_parameter_passthrough_value
&redirect_uri=http://localhost:4200/profile?platform=youtube
&access_type=offline
&response_type=code
&client_id=[HIDDEN]
After code is parsed, I exchange the code for access code:
POST => https://oauth2.googleapis.com/token
?client_id=[HIDDEN]
&client_secret=[HIDDEN]
&code=[HIDDEN]
&grant_type=authorization_code
&redirect_uri=http://localhost:2222/youtube/oauth
Response:
data: {
error: 'redirect_uri_mismatch',
error_description: 'Bad Request'
}
Apparently, the redirect_uri has to match the initial request's uri.
Problem solved, feel free to upvote for visibility - thanks.
Source: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3

Authentication session is not defined

I try to use Google Photos API to upload my images, base on the steps of the following link.
https://developers.google.com/photos/library/guides/upload-media
After following the Using OAuth 2.0 for Web Server Applications, I just get the Oauth2.0_token response(a JSON format with access_token, refresh_token...). However, after I put this token string with "Bearer " into request headers, the response is error 401, the error message is "code 16 Authentication session is not defined".
I cannot find any information to deal with it, thank for any help.
You probably have incorrect permissions. Make sure you request the token with the appropriate scope. For write-only access you need 'https://www.googleapis.com/auth/photoslibrary.appendonly'
src: https://developers.google.com/photos/library/guides/authentication-authorization#what-scopes
One reason this might be happening is that you initially authorized your user for read-only access. If you went through the authorization flow with a .readonly scope, your bearer token reflects that authorization (and the token is retained in your credentials file). If you change your scope but don't get a new auth token you will get this error when trying to upload. Simply redo the authorization flow with the new scope defined:
SCOPES = 'https://www.googleapis.com/auth/photoslibrary'
store = file.Storage('path_to_store')
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('google_credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
and your store will be populated with a new token that can be used for uploading.
You say you "just get the Oauth2.0_token response(a JSON format with access_token, refresh_token...)" and "put this token string with "Bearer " into request headers".
Unfortunately documentation on this isn't super clear in a lot of places. What you are supposed to provide after "Bearer" is the "access_token" field only, not the entire JSON string with all the token fields in it. For reference, this is a single string of random looking characters which probably starts with "ya29." and is pretty long - in my case it's 170 characters.

OAuth 1.0b receiving access token

Until few days ago everything worked fine. But after some changes on FitBit new user can not get OAuth handshake anymore. The problem is when I receive temporary tokens and make call to finish handshake and receive credentials.
So in first step I get:
TOKEN: 1a227cfde686220183763946a98173bc and VERIFIER: p2g5ims7o4ffscev603rbif05g
and in second step I use theme to make call to https://api.fitbit.com/oauth/access_token ...
Signature Base String is:
POST&https%3A%2F%2Fapi.fitbit.com%2Foauth%2Faccess_token&oauth_consumer_key%3D7c5e888aa3dd4d17a26d82a7f541b278%26oauth_token%3D1a227cfde686220183763946a98173bc%26oauth_nonce%3D5hw45lgu%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1391094796%26oauth_verifier%3Dp2g5ims7o4ffscev603rbif05g%26oauth_version%3D1.0
And by that I receive header (with signature calculated using the same function as in first step)
Authorizing with HEADER: OAuth oauth_consumer_key="7c5e888aa3dd4d17a26d82a7f541b278",oauth_token="1a227cfde686220183763946a98173bc",oauth_nonce="5hw45lgu",oauth_signature="X4udgn9A7Q2xI%2FN38QELl%2BIDVqM%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1391094796",oauth_verifier="p2g5ims7o4ffscev603rbif05g",oauth_version="1.0"
That should work but I get 401 error saying:
{"errors":[{"errorType":"oauth","fieldName":"oauth_access_token","message":"Invalid signature or token 'JNGSIMomid/oghtWGrz7crC6KhM=' or token '6c45d0ce39195e848da14cad0a4f9719'"}],"success":false}
I have been working od that for 7 hours now ... and as far as I can see everything is OK ... Error is saying about field name oauth_access_token ... This fields doesn't even exist. I tried anyway and recived error saying that security is not OK ...
Any Idea?
I had the same problem. After doing some research I noticed that the API has changed and the lib I was using was out dated.
To fix that, I updated my lib and did some code changes.
Here is the link of a .Net implementation after the change:
https://github.com/aarondcoleman/Fitbit.NET/wiki/Breaking-Change-on-1-24-2014-as-a-result-of-OAuth-update-in-Fitbit-API
Regards,
Fredy

BadRequest when calling ProcessUserAuthorization after requesting "plus.login" scope

I have problems while updating code to new scope. Currently I use userinfo.profile and everything works Ok.
According to Google+ OAuth 2.0 scopes new plus.me scope allows application to know who user is, and plus.login also gives additional access (to age, language, circles, ...).
If I replace userinfo.profile with plus.me - everything works Ok: method WebServerClient.RequestUserAuthorization authorizes user and ProcessUserAuthorization gives me a token.
But if I ask plus.login scope instead - Google adds additional query parameters to my callback and next call to WebServerClient.ProcessUserAuthorization fails , because implementation uses current rul to make new redirect_url, striping "known" parameters and leaving "new unknown" Google parameters. his redirect_url doesn't match on registered in Google Api Console and Google server returns 400 response.
Here is success response from authorization with plus.me scope (from NetOpenAuth.Messaging.Channel log):
Incoming HTTP request: GET http://localhost:40004/Me/LoginComplete?from=Google&state=TWXf6Zq3XYSlwyfCDt3GiQ&code=4/qC_KeuiykcVm1sayIyEdnBjiklxz.AoMfk5TqaXQcsNf4jSVKMpY-GxwThAI
After binding element processing, the received EndUserAuthorizationSuccessAuthCodeResponse (2.0) message is:
code: 4/qC_KeuiykcVm1sayIyEdnBjiklxz.AoMfk5TqaXQcsNf4jSVKMpY-GxwThAI
state: TWXf6Zq3XYSlwyfCDt3GiQ
from: Google
And here is (success) authorization response with plus.login scope:
Incoming HTTP request: GET http://localhost:40004/Me/LoginComplete?from=Google&state=26R-O3YN6u3-5EKIlJzFFw&code=4/zOoeVq8vec068x2-CyPq4PjPNtRT.osemzp8Zl7sQsNf4jSVKMpbcmWQThAI&authuser=0&prompt=consent&session_state=27ca4bd2e70d0721bc1fa781b900a558e59fe4c7..d409
After binding element processing, the received EndUserAuthorizationSuccessAuthCodeResponse (2.0) message is:
code: 4/zOoeVq8vec068x2-CyPq4PjPNtRT.osemzp8Zl7sQsNf4jSVKMpbcmWQThAI
state: 26R-O3YN6u3-5EKIlJzFFw
from: Google
authuser: 0
prompt: consent
session_state: 27ca4bd2e70d0721bc1fa781b900a558e59fe4c7..d409
Call for token (for plus.me scope) will be successful:
Prepared outgoing AccessTokenAuthorizationCodeRequestC (2.0) message for https://accounts.google.com/o/oauth2/token:
code: 4/qC_KeuiykcVm1sayIyEdnBjiklxz.AoMfk5TqaXQcsNf4jSVKMpY-GxwThAI
redirect_uri: http://localhost:40004/Me/LoginComplete?from=Google
grant_type: authorization_code
client_id: 175802076419.apps.googleusercontent.com
client_secret: ********
But with plus.login scope 3 new parameters (authuser, prompt, session_state) are transferred to redirect_url param:
Prepared outgoing AccessTokenAuthorizationCodeRequestC (2.0) message for https://accounts.google.com/o/oauth2/token:
code: 4/zOoeVq8vec068x2-CyPq4PjPNtRT.osemzp8Zl7sQsNf4jSVKMpbcmWQThAI
redirect_uri: http://localhost:40004/Me/LoginComplete?from=Google&authuser=0&prompt=consent&session_state=27ca4bd2e70d0721bc1fa781b900a558e59fe4c7..d409
grant_type: authorization_code
client_id: 175802076419.apps.googleusercontent.com
client_secret: ********
And as soon as this redirect_url does not match registered I receive error:
https://accounts.google.com/o/oauth2/token returned 400 BadRequest: Bad Request
OAuth2 spec says that params code and state are required in authorization response and says noting about adding other parameters. But it also says that
The client MUST ignore unrecognized response parameters
Does this mean that this is DNOA issue and not Google one?
May be DNOA must add nullable responseUri parameter to ProcessUserAuthorization and use it instead of guessing from current url...
What's the easiest workaround (except using Google library)?
Update:
Here is original request for /oauth
Prepared outgoing EndUserAuthorizationRequestC (2.0) message for https://accounts.google.com/o/oauth2/auth:
client_id: 175802076419.apps.googleusercontent.com
redirect_uri: http://localhost:40004/Me/LoginComplete?from=Google
state: TWXf6Zq3XYSlwyfCDt3GiQ
scope: https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.me
response_type: code

Resources