Our application is managing Office 365 calendars without requiring explicit consent from users using the Office 365 Exchange Online API. This works as expected for existing installations at customers, but for new customer all requests to the Exchange Online API return a 401 Unauthorized
response. We've narrowed this down to a roles claim missing in the JWT token.
Our question is if this roles claim missing in the JWT is a bug, or if this is by design. Perhaps someone from the Azure AD team can share their thoughts.
How to reproduce
In Azure AD, we've created an app registration. A public key has been uploaded in order to authenticate via ADAL4j. Next to this, some application permissions have been granted to Exchange Online:
We can successfully request a access token via ADAL4j, using https://outlook.office365.com/
as the Resource Id. The JWT looks something like this (removed some irrelevant information):
{
typ: "JWT",
alg: "RS256",
},
{
aud: "https://outlook.office365.com/",
iss: "https://sts.windows.net/yyy/",
app_displayname: "Test",
appid: "app-id",
ver: "1.0"
}
As can be seen, the property roles
is missing in the JWT token.
When calling the Exchange Online API (e.g. https://outlook.office365.com/api/v2.0/users/[email protected]/calendars
), sending the JWT as a Bearer token, a 401 Unauthorized
is returned. The x-ms-diagnostics
header mentions:
2000008;reason="The token contains no permissions, or permissions can not be understood.";error_category="invalid_grant"
Expected behaviour
When using an old application registration (created using the Azure Classic Portal, if I recall correctly), the JWT does contain a Roles
property with the role we've requested:
{
typ: "JWT",
alg: "RS256",
},
{
aud: "https://outlook.office365.com/",
iss: "https://sts.windows.net/yyy/",
app_displayname: "Test",
appid: "app-id",
roles: [
"Calendars.ReadWrite.All"
],
ver: "1.0"
}
Using this JWT as a Bearer token when calling the Exchange Online API works as expected.
Workaround
We've worked around the issue by using the Grant Permissions button for the new app registration:
Now, the Calendars.ReadWrite.All
role is present in the JWT, so everything is working as expected.
Question
In the past we've never had to execute the Grant Permissions action. Also, this page mentions (emphasis added):
As an administrator, you can also consent to an application's delegated permissions on behalf of all the users in your tenant. Administrative consent prevents the consent dialog from appearing for every user in the tenant, and can be done in the Azure portal by users with the administrator role. From the Settings page for your application, click Required Permissions and click on the Grant Permissions button
However, the "Read and write calendars in all mailboxes" permission is an application permission, and not a delegated permission, as mentioned at this page.
Is the workaround the correct solution to our missing Roles claim issue, or is something else wrong on the Azure AD side?