新的 Azure AD 应用程序在通过管理门户更新之前无法运行
New Azure AD application doesn't work until updated through management portal
我使用 AAD Graph API 在 Azure AD 中创建了一个新应用程序。 ()
不幸的是,在我访问 Azure 管理门户中的应用程序配置页面并进行外观更改并保存之前,它不允许我的客户端访问请求的资源。删除更改并再次保存后,它仍然有效。
更改前和更改后退步骤之前的应用程序清单文件完全相同(如 diff.exe 中所说它们相同)。
对比应用认证时返回的JWT token,发现post-change access token包含"roles"部分。在管理门户中保存应用程序之前返回的访问令牌中不存在整个 "roles" 部分。
因此,Azure 管理门户似乎在保存更改时对应用程序执行 "something"。问题是它是什么,我可以使用 AAD 图做同样的事情吗 API?
有几个问题。 Azure 后端的一些错误现在已经修复,还有一些我不知道是必要的对 API 的缺失调用。
多亏了 MS 支持中一些非常乐于助人的人,我们才能够让它工作。
创建应用程序时,您需要执行以下操作:
- 创建一个 application 对象。
- 为应用程序设置 RequiredResourceAccess,即。应用程序对 Azure Graph API 等具有哪些权限。这是在门户的 "permissions to other applications" 设置中配置的内容。您可以通过手动配置权限获取必要的 GUID,然后查看应用程序的 AAD 清单文件。
- 为应用程序创建 service principal。
- 将 AppRoleAssignments 添加到服务主体。
最后一部分是我之前遗漏的部分。即使您已经在应用程序对象上配置了 RequiredResourceAccess,服务主体仍然需要 AppRoleAssignments 才能真正拥有访问资源的权限。
创建 AppRoleAssignments 时,确定要分配哪个 PrincipalId 有点棘手,因为这是其他资源的服务主体的 AAD ObjectId。
这是添加 AppRoleAssignment 以访问 Azure AD Graph API 的片段。 client
是一个 ActiveDirectoryClient 实例,sp
是我的应用程序的 ServicePrincipal:
// find the azure ad service principal
var aadsp =
client.ServicePrincipals.Where(csp => csp.AppId == "00000002-0000-0000-c000-000000000000")
.ExecuteSingleAsync().Result;
// create the app role assignment
var azureDirectoryReadAssignment = new AppRoleAssignment
{
PrincipalType = "ServicePrincipal",
PrincipalId = Guid.Parse(sp.ObjectId), //
Id = Guid.Parse("5778995a-e1bf-45b8-affa-663a9f3f4d04"), // id for Directory.Read
// azure active directory resource ID
ResourceId = Guid.Parse(aadsp.ObjectId) // azure active directory resource ID
};
// add it to the service principal
sp.AppRoleAssignments.Add(azureDirectoryReadAssignment);
// update the service principal in AAD
await sp.UpdateAsync();
我的经验是你需要等待很短的时间,可能是 2-3 分钟,新创建的对象在 AAD 中生效,然后你可以使用新的应用程序进行身份验证。
除了上面 RasmusW 的回答之外,根据您要实现的目标,您可能还需要做一些其他事情。
- 如果您希望委派权限起作用,您还需要将 Oauth2PermissionGrant 添加到根级别的 Oauth2PermissionGrants 集合中。这应该有呼叫者 SPN ObjectId 的 clientId,被叫 SPN 对象 ID 的 ResourceId。 Oauth2PermissionGrant 的 Scope 值为 key。它应该有 space 个分隔值。这里的每个值都来自目标 SPN 上的 Oauth2Permission 对象的 'Value' 属性。
- 此外,您可能还需要处于适当的 DirectoryRole 中,例如目录读者。
我使用 AAD Graph API 在 Azure AD 中创建了一个新应用程序。 (
不幸的是,在我访问 Azure 管理门户中的应用程序配置页面并进行外观更改并保存之前,它不允许我的客户端访问请求的资源。删除更改并再次保存后,它仍然有效。 更改前和更改后退步骤之前的应用程序清单文件完全相同(如 diff.exe 中所说它们相同)。
对比应用认证时返回的JWT token,发现post-change access token包含"roles"部分。在管理门户中保存应用程序之前返回的访问令牌中不存在整个 "roles" 部分。
因此,Azure 管理门户似乎在保存更改时对应用程序执行 "something"。问题是它是什么,我可以使用 AAD 图做同样的事情吗 API?
有几个问题。 Azure 后端的一些错误现在已经修复,还有一些我不知道是必要的对 API 的缺失调用。 多亏了 MS 支持中一些非常乐于助人的人,我们才能够让它工作。
创建应用程序时,您需要执行以下操作:
- 创建一个 application 对象。
- 为应用程序设置 RequiredResourceAccess,即。应用程序对 Azure Graph API 等具有哪些权限。这是在门户的 "permissions to other applications" 设置中配置的内容。您可以通过手动配置权限获取必要的 GUID,然后查看应用程序的 AAD 清单文件。
- 为应用程序创建 service principal。
- 将 AppRoleAssignments 添加到服务主体。
最后一部分是我之前遗漏的部分。即使您已经在应用程序对象上配置了 RequiredResourceAccess,服务主体仍然需要 AppRoleAssignments 才能真正拥有访问资源的权限。
创建 AppRoleAssignments 时,确定要分配哪个 PrincipalId 有点棘手,因为这是其他资源的服务主体的 AAD ObjectId。
这是添加 AppRoleAssignment 以访问 Azure AD Graph API 的片段。 client
是一个 ActiveDirectoryClient 实例,sp
是我的应用程序的 ServicePrincipal:
// find the azure ad service principal
var aadsp =
client.ServicePrincipals.Where(csp => csp.AppId == "00000002-0000-0000-c000-000000000000")
.ExecuteSingleAsync().Result;
// create the app role assignment
var azureDirectoryReadAssignment = new AppRoleAssignment
{
PrincipalType = "ServicePrincipal",
PrincipalId = Guid.Parse(sp.ObjectId), //
Id = Guid.Parse("5778995a-e1bf-45b8-affa-663a9f3f4d04"), // id for Directory.Read
// azure active directory resource ID
ResourceId = Guid.Parse(aadsp.ObjectId) // azure active directory resource ID
};
// add it to the service principal
sp.AppRoleAssignments.Add(azureDirectoryReadAssignment);
// update the service principal in AAD
await sp.UpdateAsync();
我的经验是你需要等待很短的时间,可能是 2-3 分钟,新创建的对象在 AAD 中生效,然后你可以使用新的应用程序进行身份验证。
除了上面 RasmusW 的回答之外,根据您要实现的目标,您可能还需要做一些其他事情。
- 如果您希望委派权限起作用,您还需要将 Oauth2PermissionGrant 添加到根级别的 Oauth2PermissionGrants 集合中。这应该有呼叫者 SPN ObjectId 的 clientId,被叫 SPN 对象 ID 的 ResourceId。 Oauth2PermissionGrant 的 Scope 值为 key。它应该有 space 个分隔值。这里的每个值都来自目标 SPN 上的 Oauth2Permission 对象的 'Value' 属性。
- 此外,您可能还需要处于适当的 DirectoryRole 中,例如目录读者。