我们的应用程序正在管理Office 365日历,而无需使用Office 365 Exchange Online API的用户明确同意。这适用于客户的现有安装,但对于新客户,对Exchange Online API的所有请求都会返回401 Unauthorized
响应。我们已将此范围缩小到JWT令牌中缺少的角色声明。
我们的问题是,如果JWT中缺少此角色是一个错误,或者这是设计错误。也许来自Azure AD团队的人可以分享他们的想法。
在Azure AD中,我们已创建了应用注册。已上载公钥以通过ADAL4j进行身份验证。接下来,已向Exchange Online授予了一些应用程序权限:
我们可以使用https://outlook.office365.com/
作为资源ID,通过ADAL4j成功请求访问令牌。 JWT看起来像这样(删除了一些不相关的信息):
{
typ: "JWT",
alg: "RS256",
},
{
aud: "https://outlook.office365.com/",
iss: "https://sts.windows.net/yyy/",
app_displayname: "Test",
appid: "app-id",
ver: "1.0"
}
可以看出,JWT令牌中缺少属性roles
。
调用Exchange Online API(例如https://outlook.office365.com/api/v2.0/users/user@tenant.onmicrosoft.com/calendars
)时,将JWT作为承载令牌发送,将返回401 Unauthorized
。 x-ms-diagnostics
标题提及:
2000008;reason="The token contains no permissions, or permissions can not be understood.";error_category="invalid_grant"
使用旧的应用程序注册(使用Azure经典门户创建,如果我没记错),JWT确实包含Roles
属性,其中包含我们已请求的角色:
{
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"
}
在调用Exchange Online API时,使用此JWT作为承载令牌按预期工作。
我们通过使用新的应用注册的授予权限按钮来解决此问题:
现在,JWT中存在Calendars.ReadWrite.All
角色,因此一切都按预期工作。
过去,我们从未执行过授予权限操作。此外,this page提及(强调添加):
作为管理员,您也可以同意申请 代表租户中的所有用户委派权限。 管理同意可防止出现同意对话框 租户中的每个用户,并且可以由Azure用户在Azure门户中完成 具有管理员角色。从您的设置页面 单击“应用程序”,单击“必需权限”,然后单击授予 权限按钮
然而,"所有邮箱中的"读写日历"如this page所述,权限是应用权限,而不是委托权限。
解决方法是否是我们缺少的角色声明问题的正确解决方案,或者是否在Azure AD方面出现了其他问题?
答案 0 :(得分:3)
解决方法是正确的解决方案。当您的应用程序需要应用程序权限时,管理员必须同意通过单击"授予权限"按钮(如您所做)或将admin_consent传递给登录URL。这适用于AAD v1应用程序模型。对于AAD v2应用程序模型,有一种不同的方式来获得管理员同意。更多信息here。
过去(Azure经典门户),当您向应用程序添加应用程序权限时,会自动授予同意。在新的Azure门户中并非如此。