Reputation: 2236
I had a problem reading all users calendar's which I explained here: Using Microsoft graph to read all users calendars
According to the documentation this was available, however it didn't work and the reply was to best use the flow described in the following article (daemon or service app).
Things I did: - I registered my web app in Azure portal under active directory. I set it as a web application (not a native client app). I set it as multi-tenant and gave application permissions. - I make a key, edited manifest and uploaded this.
What I'm doing is:
1) get the tenant ID of the user, at this stage the admin user gives permission.
2) as described in the article: I only use the tenantId that I get back, I don't do anything with the access token.
3) I then get a token from https://login.windows.net/TENANT_ID/oauth2/token?api-version=1.0 this seems to work as well (after a lot of searching).
4) When I put the access token I got back into https://jwt.io I get a valid result (or so it seems at least), see here: https://www.evernote.com/shard/s29/sh/5128795e-e7fd-4b8e-a779-5795cd83a66d/6e67979e1b628b06da60a5dcd5ba99a4
5) Whatever request I make with the access token afterwards I always get:
The token contains no permissions, or permissions can not be understood.
These are the scopes I requested in step 1.
SCOPES = [ "openid" "Calendars.Read", "User.Read.All", "offline_access" ]
A couple of questions:
Upvotes: 1
Views: 6152
Reputation: 2264
To run the application as daemon you need to login using application identity (using the appid and appkey).
Resource:
"https://graph.microsoft.com/"
I'm using the ADAL library for dotnet (I'm sure you can find something similar for you), this is my code for login:
public static AuthenticationResult LoginForDaemon(string InTenantName, string InClientId, string InClientAppKey, string InResourceId)
{
Check.Require(!string.IsNullOrEmpty(InTenantName), "InTenantName must be provided");
Check.Require(!string.IsNullOrEmpty(InClientId), "InClientId must be provided");
Check.Require(!string.IsNullOrEmpty(InClientAppKey), "InClientAppKey must be provided");
Check.Require(!string.IsNullOrEmpty(InResourceId), "InResourceId must be provided");
try
{
var clientCredential = new ClientCredential(InClientId, InClientAppKey);
var authContext = new AuthenticationContext(string.Format(CultureInfo.InvariantCulture, @"https://login.microsoftonline.net/{0}/oauth2/logout", InTenantName));
return authContext.AcquireToken(InResourceId, clientCredential);
}
catch (AdalSilentTokenAcquisitionException ex)
{
if (ex.Message.Contains("Failed to acquire token silently"))
return null;
else
throw ex;
}
}
Upvotes: 0
Reputation: 14649
Based on the blog, it request the id token first. What’s the request for the app-only token you were using? The endpoint https://login.windows.net/common/oauth2/token is the old one to get the token.
You can refer to the REST below to acquire the app-only token(refer to here):
POST: https://login.microsoftonline.com/o365e3w15.onmicrosoft.com/oauth2/token
grant_type=client_credentials&client_id={clientID}&client_secret={encodedSecret}&resource=https%3A%2F%2Fgraph.microsoft.com
Then we can get the calendars of users we want via the REST below:
GET: https://graph.microsoft.com/v1.0/users/[email protected]/calendarview?startDateTime=2016-05-01T00:00:00&endDateTime=2016-06-01T08:00:00
authorization: bearer {token}
And in the sample above, I used the Microsoft Graph(https://graph.microsoft.com) to request the calendars which is an unified endpoint for multiple APIs from Microsoft cloud services. If you were developing with Exchange REST, you can also use the single canlenader endpoint https://outlook.office.com replace the resource in the token request.
Upvotes: 1