我有一个多租户原生应用,可以从Microsoft Graph调用设备信息。本机应用程序和Microsoft Graph之间没有Web API。请求的范围是:User.Read,Directory.Read.All,Device.Read
来自客户租户的客户管理员已使用以下网址向该应用授予了权限:
https://login.microsoftonline.com/{Tenant Domain}/oauth2/authorize?client_id={ClientID Of App}&response_type=code&prompt=admin_consent
完成后,返回的同意值为TRUE,应用程序显示在Azure AD中 - >企业应用程序 - >所有应用程序 - >具有"权限的{App Name}"显示针对Microsoft Graph的所有3个权限的部分作为" Delegated"并由#34;管理员"。
当客户租户的管理员之后登录应用程序时,该应用程序按预期工作。但是,如果非管理员用户尝试登录应用程序,则在登录后会收到错误:
需要管理员批准 - {App name}需要访问资源的权限 在您的组织中,只有管理员才能授予。请问管理员 在您可以使用之前授予此应用程序的权限。信息: AADSTS90094:该授权需要管理员权限。
同样,管理员已同意该应用。
此外,该应用程序显示在开发公司的Azure AD中的租户节目中 - >应用注册 - > (过滤"所有应用" - > {App Name} - > Manifest显示:
{
"appId": "{Hidden from StackOverflow}",
"appRoles": [],
"availableToOtherTenants": true,
"displayName": "{Hidden from StackOverflow}",
"errorUrl": null,
"groupMembershipClaims": null,
"optionalClaims": null,
"acceptMappedClaims": null,
"homepage": null,
"informationalUrls": {
"privacy": null,
"termsOfService": null
},
"identifierUris": [],
"keyCredentials": [],
"knownClientApplications": [],
"logoutUrl": null,
"oauth2AllowImplicitFlow": false,
"oauth2AllowUrlPathMatching": false,
"oauth2Permissions": [],
"oauth2RequirePostResponse": false,
"objectId": "{Hidden from StackOverflow}",
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [],
"publicClient": true,
"replyUrls": [
"{Hidden from StackOverflow}"
],
"requiredResourceAccess": [{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "06da0dbc-49e2-44d2-8312-53f166ab848a",
"type": "Scope"
},
{
"id": "11d4cd79-5ba5-460f-803f-e22c8ab85ccd",
"type": "Scope"
}
]
}],
"samlMetadataUrl": null
}
相关代码:
public static async Task<Device> GetDeviceByName(string DeviceName)
{
IGraphServiceDevicesCollectionPage result = await AuthHelper.GetAuthenticatedClient().Devices.Request().GetAsync();
foreach (Device device in result)
{
if (device.DisplayName == DeviceName)
{
return device;
}
}
return new Device();
}
static string ClientId = "{Hidden from StackOverflow}";
public static string[] Scopes = { "User.Read", "Directory.Read.All", "Device.Read" };
public static string TokenForUser = null;
public static PublicClientApplication IdentityClientApp =
new PublicClientApplication(ClientId, "https://login.microsoftonline.com/organizations");
private static GraphServiceClient graphClient = null;
public static GraphServiceClient GetAuthenticatedClient()
{
if (graphClient == null)
{
graphClient = new GraphServiceClient("https://graph.microsoft.com/v1.0",
new DelegateAuthenticationProvider(async(requestMessage) =>
{
var token = await GetTokenForUserAsync();
requestMessage.Headers.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", token);
}));
}
return graphClient;
}
public static async Task<string> GetTokenForUserAsync()
{
AuthenticationResult authResult;
try
{
authResult = await IdentityClientApp
.AcquireTokenSilentAsync(Scopes, IdentityClientApp.Users.First());
}
catch
{
authResult = await IdentityClientApp
.AcquireTokenAsync(Scopes);
}
TokenForUser = authResult.AccessToken;
return TokenForUser;
}
public static void SignOut()
{
foreach (var user in IdentityClientApp.Users)
{
IdentityClientApp.Remove(user);
}
graphClient = null;
TokenForUser = null;
}
我一直在研究这个问题大约一个星期,我无法弄清楚我做错了什么。我查看了docs.microsoft.com上与此相关的大量文档,大多数示例都使用Web API。