Setting signInAudience using azure graph API -- Invalid JSON - azure-active-directory

I try to set the signInAudience using the Azure Graph API (with the azure cli / az rest command) from inside powershell using the following code:
$body='{"signInAudience":"AzureADAndMicrosoftAccounts"}'
echo $body
Test-Json -Json $body
az rest --method PATCH --uri https://graph.microsoft.com/v1.0/applications/$application_object_id --body $body --headers "Content-Type=application/json"
Which should (according to the rest documentation here) Update the signInAudience auf the Azure AD Application.
This is the result:
{"signInAudience":"AzureADAndMicrosoftAccounts"}
True
ValidationError: Bad Request({
"error": {
"code": "BadRequest",
"message": "Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.",
"innerError": {
"date": "2020-10-13T10:48:48",
"request-id": "f29fd020-33aa-4cda-b98e-130d1434cd85",
"client-request-id": "f29fd020-33aa-4cda-b98e-130d1434cd85"
}
}
})
Why does this not work?
Other Changes can be set ussing this API, the following call does for example work.
az rest --method PATCH --uri https://graph.microsoft.com/v1.0/applications/${azuread_application.main_application.object_id} --body '{"api":{"requestedAccessTokenVersion": 2}}' --headers "Content-Type=application/json"

According to my test, if we enclose the entire string in single quotation, the Azure CLI command az rest will not identity double quotation. It just identity the body as {signInAudience:AzureADAndMicrosoftAccounts}. So I suggest you use double quotation to enclose the entire string.
Besides, when you want to allow users with a personal Microsoft account, or a work or school account in any organization’s Azure AD tenant to access the application, the signInAudience should be set as AzureADandPersonalMicrosoftAccount. For more details, please refer to here.
for example
$body="{'signInAudience':'AzureADandPersonalMicrosoftAccount'}"
az rest --method PATCH --uri https://graph.microsoft.com/v1.0/applications/<object id> --body $body --headers "Content-Type=application/json"

Related

Retrieve PubSub Schema from external IP address with API Key

I have created a PubSub schema
I have created an API key with no restrictions
I wish to cURL/Get this schema from an address outside of GCP
I tried the below request but it's denied as per below
me#J-5CG2200NLY:~/go/$ curl https://pubsub.googleapis.com/v1/projects/myprojetc199/schemas/pbschema_1?key=mylongkeyxxxxxxxxxxxx
{
"error": {
"code": 403,
"message": "User not authorized to perform this action.",
"status": "PERMISSION_DENIED"
}
}
How can I authenticate my request?
Thanks in advance
Pub/Sub does not support the use of API keys as an authentication method (as noted in the documentation). API keys are used for quota attribution for requests. You would have to use one of the alternative authentication methods like OAuth in order to retrieve the schema via a cURL/Get.
If you are logged in via gcloud on an account that has permission to get schemas, you can then get the access token:
gcloud auth application-default print-access-token
Now, you can use that access token in a curl command:
PROJECT=my-project
SCHEMA=my-schema
ACCESS_TOKEN=<token printed out above>
curl -H "Authorization: Bearer $ACCESS_TOKEN" -X GET https://pubsub.googleapis.com/v1/projects/$PROJECT/schemas/$SCHEMA

Unable to generate access token for microsoft graph online meeting api

I have tried everything but somehow unable to generate token or the token that is generated does not work. Please help with what I am doing wrong. I want the token to create an online meeting.
Sharing requests below which I have tried
Generate token with client credentials grant type
REQUEST:
POST 'https://login.microsoftonline.com/CXXXXXXX/oauth2/token'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'password=CXXXXXXX'
--data-urlencode 'grant_type=client_credentials'
--data-urlencode 'scope=OnlineMeetings.ReadWrite'
--data-urlencode 'client_id=CXXXXXXXCXXXXXXX-464c-965a-CXXXXXXXCXXXXXXX'
--data-urlencode 'username=CXXXXXXX#gmail.com'
--data-urlencode 'client_secret=CXXXXXXX6ryCXXXXXXXuV.zu8SmW~D_'
Save the token generated- Using this in https://graph.microsoft.com/v1.0/me/onlineMeetings gives error - Access token validation failure. Invalid audience
Use this token as assertion as follows
POST 'https://login.microsoftonline.com/learn123456789.onmicrosoft.com/oauth2/token'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer'
--data-urlencode 'scope=OnlineMeetings.ReadWrite'
--data-urlencode 'client_id=CXXXXXXXCXXXXXXX-464c-965a-CXXXXXXXCXXXXXXX'
--data-urlencode 'client_secret=CXXXXXXX6ryCXXXXXXXuV.zu8SmW~D_'
--data-urlencode 'resource=https://graph.microsoft.com/'
--data-urlencode 'requested_token_use=on_behalf_of'
--data-urlencode 'assertion=tokenFromFirstAPI'
Also tried this api
https://login.microsoftonline.com/common/oauth2/authorize?client_id=CXXXXXXXCXXXXXXX-464c-965a-CXXXXXXXCXXXXXXX&response_type=token&resource=XXXXXXX6-ba00-4fd7-XXXXXXXXX3
Error is
Assertion audience does not match the Client app presenting the assertion. The audience in the assertion was '00000002-0000-0000-c000-000000000000' and the expected audience is 'clientID' or one of the Application Uris of this application with App ID XXX. The downstream client must request a token for the expected audience (the application that made the OBO request) and this application should use that token as the assertion.
No token works in this - https://graph.microsoft.com/v1.0/me/onlineMeetings
Getting - "Access token validation failure. Invalid audience.",
Please help, what am I doing wrong?
Thanks Carl bit it did not work
Have even given all the permissions as suggested above.
ERROR- Bad Request - 400 - 819ms
{ "error": { "code": "AuthenticationError", "message": "Error authenticating with resource", "innerError": { "date": "2020-12-27T09:36:57", "request-id": "4e01eff1-9eb5-42dd-9009-dbdd85aca49a", "client-request-id": "5effa441-d7f6-5ef7-5066-1d7153f39712" } }
As your error message says, your token audience is invalid , because you set the wrong scope when requesting the token. You should set the scope to https://graph.microsoft.com/.default or https://graph.microsoft.com/OnlineMeetings.ReadWrite, in addition, the api call only supports delegated permissions, so you can't use the client credential flow to get the token. For the /me endpoint, the user needs to log in, so you need Use auth code flow to obtain an access token.
Or, there is a simpler method, you can use Graph Explorer to test, you only need to log in to the user and add permissions.
Update:
I noticed that you use 3 methods to get the token.
First of all, for the first method, you are using a v1.0 endpoint and use the client credential flow to obtain the token. What you need to pay attention to is that when you use v1.0 authentication, you cannot use scope, you should use resource. In addition, when you use the client credential flow, you cannot use the v1.0 version , you need to use the beta version, and because the client credential flow is a flow without user login, you cannot call the /me endpoint, you should call the /users endpoint. (Note: When you use the beta version and use the client credential flow, according to the documentation: Administrators must create an application access policy and grant it to a user, authorizing the app configured in the policy to create an online meeting on behalf of that user (user ID specified in the request path).)
The complete request is:
POST https://login.microsoftonline.com/{tenant}/oauth2/token
Content-Type: application/x-www-form-urlencoded
client_id=535fb089-9ff3-47b6-9bfb-xxxxxxxxxx
&resource=https://graph.microsoft.com/
&client_secret=qWgdYAmab0YSkuLxxxxxxx
&grant_type=client_credentials
api call:
https://graph.microsoft.com/beta/users/{userId}/onlineMeetings
For the second method, I noticed that you are using OBO flow, and then you pass in the wrong access token obtained by the first method as an assertion, so the access token you obtained using this flow is definitely not correct. . In addition, if you don't have a back-end API, please do not use this flow. This flow requires you to have a middle-tier API, and it is cumbersome to use.
Your third method is also wrong, your resource should be: https://graph.microsoft.com
To summarize: If you want to use the client credential flow without user login, please refer to my update. If you don't have a backend api, please do not use OBO flow.
IMAGE of ERROR
Error in following URL
"message": "Error authenticating with resource",
https://developer.microsoft.com/en-us/graph/graph-explorer

Unable to delete user from Azure AD B2C

According to this article it should be possible to delete a user from Azure AD B2C using the Microsoft Graph API: https://learn.microsoft.com/en-us/azure/active-directory-b2c/microsoft-graph-operations (more specifically: https://learn.microsoft.com/en-us/graph/api/user-delete)
I have set the User.ReadWrite.All permission (for permission type Application) and granted admin consent.
However, when calling the corresponding endpoint with a http DELETE request, it fails with the following response:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
},
"requestId": "b129b3a7-a0e9-42db-aa7a-97da31590095",
"date": "2020-11-04T12:53:32"
}
}
Other operations (such as listing and updating users) work perfectly fine. Does anyone know what causes this behavior? Any help is highly appreciated.
Update:
This is a sample of a request which I try to send to the Graph API:
Postman Curl request
Make sure you are calling Microsoft Graph and the configured permissions are under Microsoft Graph.
Based on your Curl request, you are calling Azure AD Graph (endpoint https://graph.windows.net).
The Microsoft Graph endpoint is https://graph.microsoft.com.
If your permissions are set correctly under Microsoft Graph, try to use DELETE https://graph.microsoft.com/v1.0/users/{user-id} to delete the user.

Google Cloud Platform REST API: Acquiring Access Token and API Key

I wish to use the Google Cloud Platform (GCP) REST API locally, starting with the apps.services.versions.instances.list method.
The route works when I use "Try this API" here, but how would I use this method locally with curl?
"https://appengine.googleapis.com/v1/apps/$APPSID/services/$SERVICESID/versions/$VERSIONSID/instances?key=$YOUR_API_KEY" \
--compressed \
--header 'Accept: application/json' \
--header "Authorization: Bearer $YOUR_ACCESS_TOKEN"
#=>
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
How do I access $YOUR_API_KEY and $YOUR_ACCESS_TOKEN? I have been unable to find either in the official GCP docs.
The fastest way is use Cloud Shell:
List projects to get project id
gcloud projects list
# save you project id
PROJECT_ID="YOURS_PROJECT_ID"
Get ACCESS_TOKEN
ACCESS_TOKEN=$(gcloud auth print-access-token)
Get API_KEY
API_KEY=$(curl -X POST https://apikeys.googleapis.com/v1/projects/$PROJECT_ID/apiKeys?access_token=$ACCESS_TOKEN | jq -r ".currentKey")
Print API_KEY and ACCESS_TOKEN
echo $ACCESS_TOKEN
echo $API_KEY
To run above commands on local machine first you need authenticate using command gcloud auth login and follow instructions.
Alternatively api key could be readed or created from console go to Navigation Menu -> APIs & Services -> Credentials and next click on CREATE CREDENTIALS -> API Key.
By reading the documentation (clicking on question mark next to Credentials) we can read:
[YOUR_API_KEY] - "Include an API Key to identify your project, used to verify enablement and track request quotas."
[YOUR_ACCESS_TOKEN] - "Include an access (bearer) token to identify the user which completed the OAuth flow with your Client ID."
You no longer need an API key. It's a legacy feature of Google APIs, provide only an access token is enough.
In command line you can do this
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" https://....
All the Google Cloud APIs are compliant with access token authentication. Few are still compliant with API keys.
About APIKeys API
This API has been published in beta and now closed. At least the documentation part. I don't know if this API is stable or subject to change. You can create an API key per API like this (very similar to Bartosz Pelikan answer)
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
-X POST https://apikeys.googleapis.com/v1/projects/PROJECT_ID/apiKeys
As you can see, I reuse the access token authentication mode
The above answers are using an API that isn't publicly available (I reached out to GCP support an confirmed.
I recommend using the CLI tool like so:
gcloud app instances list --service core-api --project my-project-name
docs: https://cloud.google.com/sdk/gcloud/reference/app/instances/list
You'll have to a gcloud auth first and probably set your project.

Can I get an id_token from Azure AD for my app?

Using the client_credentials flow in Azure AD, I am unable to retrieve an id_token for my app.
I am experimenting with the Azure AD OAuth/OpenID endpoints, and running into some questions.
I create a simple app with minimal config through the Graph API (a beta endpoint, but still). I have removed all the headers and anonymised in code snippets below:
curl -X POST \
https://graph.microsoft.com/beta/applications \
-d '{
"displayName": "App Name",
"passwordCredentials": [
{
"endDateTime": "2299-12-30T23:00:00Z",
"startDateTime": "2019-02-14T20:19:14.686691Z",
"secretText": "<SOME KEY>",
"displayName": "Client Secret"
}
]
}'
In the response from Azure AD, I get an appId:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#applications/$entity",
"id": "<SOME GUID>",
"deletedDateTime": null,
"isFallbackPublicClient": null,
"appId": "<SOME GUID>",
...
This is enough for me to be able to retrieve an access_token from the v1 OAuth endpoint:
curl -X POST \
https://login.microsoftonline.com/tenant_id/oauth2/token \
-d 'client_id=appId&client_secret=secretText&grant_type=client_credentials'
Response:
{
"token_type": "Bearer",
"expires_in": "3600",
"ext_expires_in": "3600",
"expires_on": "1550220412",
"not_before": "1550216512",
"resource": "00000002-0000-0000-c000-000000000000",
"access_token": "<JWT access token>"
}
Since I didn't specify a resource in my call, I get the default Graph API resource.
Now, what I also would like to get is an id_token for my app. I have been able to get these tokens from other OpenID providers. However, the OpenID Connect Core spec. gives me reason to think that id_tokens are for end users only, not apps:
"The ID Token is a security token that contains Claims about the Authentication of an End-User by an Authorization Server when using a Client, and potentially other requested Claims"
(From https://openid.net/specs/openid-connect-core-1_0.html#IDToken)
Adding resource=openid to the POST to the token endpoint above won't work, since openid is a scope, not a resource.
Switching to the v2 endpoints, I get access to a scope parameter. I can obtain an access token from there by setting scope=https://graph.microsoft.com/.default, explicitly requesting the access I got by default through the v1 endpoint.
However, setting the scope to for instance scope=https://graph.microsoft.com/.default openid does not give me an id_token for my app, and the access token looks identical to the previous call.
Trying just scope=openid gives me the following error from Azure AD:
AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope openid is not valid.
All this combined leads me to believe that the OpenID providers I have used and have issued id_tokens through the client_credentials flow are breaking the spec, and that id_tokens can only be obtained for end users (using the authorization_code flow gives me an id_token from Azure AD for myself without any issues).
Is this a correct conclusion, or can I force Azure AD to issue id_tokens to apps as well as end users?
An id_token is issued when a user signs-in. Client credentail flows have no user, so no id_token is issued.
you'd need to use a flow like authorization code grant or openID connect to sign a user in. The response will have a id_token.
You cannot use the client credentials flow to get the id_token for app-only, it only returns the access_token.

Resources