Im having trouble with endpoint when using the client_credentials Grant type (http://graph.microsoft.io/en-us/docs/authorization/app_only)
https://graph.microsoft.com/v1.0/users
I get
{#333 ▼
+"error": {#314 ▼
+"code": "Authorization_RequestDenied"
+"message": "Insufficient privileges to complete the operation."
+"innerError": {#304 ▼
+"request-id": "37643af9-b9e9-4771-924f-b34c0e9d0d87"
+"date": "2016-06-22T13:38:06"
}
}
}
Im able to get my oauth token no problem using the client credentials grant
{#319 ▼
+"token_type": "Bearer"
+"expires_in": "3600"
+"ext_expires_in": "3600"
+"expires_on": "1466606585"
+"not_before": "1466602685"
+"resource": "https://graph.microsoft.com"
+"access_token": "OMITTED"
}
I have also selected the proper application permission
Read all users' full profiles
Please let me know what I'm doing wrong.
The permissions take time (10-30 mins) to propagate
Related
I've been using Microsoft Graph to try to update the profile photo of a guest user. I've tried using postman and our own front-end and always end up with the following exception:
Code: ErrorInsufficientPermissionsInAccessToken
Message: Exception of type 'Microsoft.Fast.Profile.Core.Exception.ProfileAccessDeniedException' was thrown.
Inner error:
AdditionalData:
I am, however, able to successfully retrieve the guest user's photo with a GET on both: users/{userid}/photo/$value and me/photo/$value, but unable to update it using a PUT or PATCH request on either of the URLs on both /beta/ and /v1.0/.
The request has the following scopes defined:
"scp": "AllSites.Read Calendars.Read Calendars.ReadWrite Calendars.ReadWrite.Shared Contacts.Read Directory.AccessAsUser.All EWS.AccessAsUser.All Files.Read.All Group.Read.All Group.ReadWrite.All Mail.Read Mail.Send MailboxSettings.Read MyFiles.Read Notes.Read Notifications.ReadWrite.CreatedByApp openid People.Read People.Read.All Place.Read.All Presence.Read.All profile Sites.Read.All Sites.Search.All Tasks.ReadWrite TermStore.Read.All User.Read User.Read.All User.ReadWrite UserActivity.ReadWrite.CreatedByApp UserNotification.ReadWrite.CreatedByApp"
Note the: User.ReadWrite as specified in the docs: profilephoto-update
I am specifically using the Id as opposed to the UserPrincipleName, so specifically: /users/{id}/photo/$value,
but I get the error on both of them regardless. I am making the PUT request as follows:
var photoBytes = Convert.FromBase64String(photoData);
var stream = new MemoryStream(photoBytes);
var graphServiceClient = new GraphProvider(graphToken).GraphServiceClient;
return graphServiceClient.Users[userId].Photo.Content
.Request()
.PutAsync(stream);
I am able to change the profile photo of a non-guest user, but I'm unable to do so with a guest user. Is it possible that there is an issue with Microsoft.Graph itself or am I missing something.
Thanks for reaching out to us , could you please try to add User.ReadWrite.All permission and retry again .
Thanks
I'm using this code
var app = ConfidentialClientApplicationBuilder.Create(AzureAdApplicationId)
.WithTenantId("organizations")
.WithRedirectUri(AzureAdRedirectUrl)
.WithClientSecret(AzureAdSecretKey)
.Build();
azureAdScopes = new List<string>() { "email" };
var signInRequest = app.GetAuthorizationRequestUrl(azureAdScopes);
var uri = await signInRequest.ExecuteAsync();
which produces the url
https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?scope=email+openid+profile+offline_access&...
All I need is the user's username and I don't need offline access to the user's account. How can I remove them from the scope?
You could request the url without offline_access, but Azure AD v2.0 OAuth2 Account Consent Page automatically lists "Access your data anytime" even though offline_access is not specified in scope. This is an issue related.
The Note shows in the document:
At this time, the offline_access ("Maintain access to data you have
given it access to") and user.read ("Sign you in and read your
profile") permissions are automatically included in the initial
consent to an application.
I'm trying to authenticate to my Auth0 tenant via the Swagger UI (auto-generated by Swashbuckle.AspNetCore) using client credentials.
I'm getting the following error:
Auth ErrorError, error: access_denied, description: Non-global clients
are not allowed access to APIv1
Here's a screen shot:
Open API spec looks like this:
"securitySchemes": {
"auth0": {
"type": "oauth2",
"flows": {
"clientCredentials": {
"tokenUrl": "https://example.auth0.com/oauth/token"
},
"authorizationCode": {
"authorizationUrl": "https://example.auth0.com/authorize?audience=test",
"tokenUrl": "https://example.auth0.com/oauth/token",
"scopes": { }
}
}
}
}
I suspect this has something to do with the audience not being specified. I was having a similar issue with authorization code flow, but manged to get this working by appending the audience as a query-string param to the authorizationUrl (as shown above). Unfortunately the same trick doesn't work with client credential flow (i.e. attempting to append the audience to the tokenUrl). I need to support client credential flow, as one or more of the routes need to be locked down to M2M tokens only.
Interestingly, it works if I use the global client ID / secret (found under the advanced settings of the tenant), but I'm not sure if we should use this...
Anyone else ran into this issue and if so, any luck with finding a solution?
I created an app in Azure and set it up to use Access and ID tokens.
I want to connect to different tenants and read SharePoint sites. Here are the permissions I've requested and received Admin Consent for:
For now, I have set up an App Secret but I do plan to move to a certificate later.
I have this code to get the access token and I do get an access token back:
const params = new URLSearchParams();
params.append("grant_type", "client_credentials");
params.append("scope", "https://graph.microsoft.com/.default");
params.append("client_id", process.env.client_id);
params.append("client_secret", process.env.client_secret);
var url = `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token`;
const response = await fetch(url,
{
method: 'POST',
body: params,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}
);
However when I try to read the root site below
var url = "https://graph.microsoft.com/v1.0/sites?search=*";
const response = await fetch(url,
{
method: 'GET',
headers: { 'Authorization': `Bearer ${access_token}` }
}
);
I get this error:
error: {
code: 'AccessDenied',
message: 'Either scp or roles claim need to be present in the token.',
innerError: {
'request-id': 'ec47913f-2624-4d1c-9b27-5baf05ccebfd',
date: '2019-08-16T14: 15: 37'
}
}
I checked the token at https://jwt.io/ and indeed I do not see any entry for roles or scp.
It looks like I missed a step but I cannot figure out which step.
I am getting the token like this:
https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token
What am I doing incorrectly?
The first thing to understand is that you cannot receive both Application and Delegated permissions in the same token, it is an either/or scenario. Which type you receive depends entirely on which OAuth Grant you used to request the token:
Authorization Code and Implicit return Delegated tokens with an scp property
Client Credentials return Application tokens with a roles property
The second thing is that you've requested scopes to two different APIs. Based on what you've selected, you won't have access to SharePoint through the Microsoft Graph because you've only requested access to the legacy SharePoint API. More importantly, you've only requested the Delegated User.Read scope for Graph so when you use Client Credentials to obtain the token, that token won't have any permissions.
In order to obtain an Application token for reading SharePoint sites, you'll need Sites.Read.All Microsoft Graph Application permission selected.
I'm trying the make further requests to linkedinAPI and to do so I need both token and token_secret.
I have several test accounts in linkedin, the login process success with all of them, however the token_secret stores (for all of them is empty).
Is that an error? I suspect so because using the pair token/token_secret in subsecuent oauth2 calls I get the following from linkedin
{ "errorCode": 0, "message": "[unauthorized]. The token used in the OAuth request is not valid. AQVvM2f2qefU3vULPS-R46DXN8Mnra9ImG14hzeTvMMcXvBVOEiUl4RTZCJrdFZoTfGGN1fFzLvxG-O_UWB8s8EDr35ZsgwW59y4KilndoEkr105Sg2GR90jmUxpqxU572IiARjN5gxAjfoWC4-_UupKlEtafQn23XQqvXeuLvE-FsPAaSA", "requestId": "VOAL1ULK4X", "status": 401, "timestamp": 1395348629428 }
Further details:
I check these tokens using the shell:
from allauth.socialaccount.models import SocialToken
map(lambda st: st.token_secret, SocialToken.objects.all())
And I get empty output:
[u'', u'', u'']
I found a solution myself so I'll explain it.
I'm not very into oauth2 so I don't know about the process neither if it was normal to have an empty secret_token. So I debugged a bit into the django-allauth code, and I saw that the requests they perform use only the token (no secret token)
Then I changed the library and started using the same they do: requests. And with the following simple script I can make any other request to the linkedin API:
def see_my_groups_json(request, url):
import requests
token = SocialToken.objects.get(account__user_id=request.user.pk)
resp = requests.get(url, params={'oauth2_access_token': token.token})
return resp.json()
You should check the SCOPE parameter for linkedin provider. For example, the next configuration requests permission for accessing user's email address, basic profile and to read and share updates on behalf of the user.
SOCIALACCOUNT_PROVIDERS = {
'linkedin_oauth2': {
'SCOPE': ['r_emailaddress', 'r_basicprofile', 'rw_nus'],
'PROFILE_FIELDS': ['id', 'first-name', 'last-name', 'email-address', 'picture-url', 'public-profile-url']
}
}
If after the token generation, we try to make an API call that requires some other privilege, we will get a 401 status code HTTP response.
django-allauth, by default, r_emailaddress scope or none at all, depending on whether or not SOCIALACCOUNT_QUERY_EMAIL is enabled.
Hope this helps you.