我正在尝试使用Unified API(Microsoft.Graph 1.0.1)来访问我的用户个人资料照片,但访问照片时我只收到以下错误:
代码:ErrorAccessDenied
消息:访问被拒绝。检查凭据,然后重试。
访问/列出其他用户个人资料数据工作正常,我的应用程序被添加为"公司管理员"通过PowerShell并在管理门户中设置所有权限。当我使用我的管理员用户登录的GraphExlorer时,它也可以正常工作。也通过" old" Azure Active Directory图谱API我可以读取/写入用户缩略图照片,但这不是Office 365中显示的那个。
如何获取相应的访问权限以对用户个人资料照片执行操作?
这是我使用的代码(缩写为相关部分):
class Program
{
private const string authStringMicrosoft = "https://login.microsoftonline.com/MY_APP_ID/";
private const string clientID = "MY_CLIENT_ID";
private const string clientSecret = "MY_CLIENT_SECRET";
private const string graphResourceId = "https://graph.microsoft.com";
static void Main(string[] args)
{
AsyncContext.Run(RunAsync);
Console.WriteLine("DONE");
Console.ReadLine();
}
private static async Task RunAsync()
{
var token = await GetAppTokenAsync(authStringMicrosoft, graphResourceId);
var authHelper = new AuthenticationHelper() { AccessToken = token }
var graphClient = new GraphServiceClient(authHelper);
await ListUser(graphClient);
}
private static async Task ListUser(GraphServiceClient graphClient)
{
Console.WriteLine("User-List:");
var users = await graphClient.Users.Request().GetAsync();
foreach (var user in users)
{
Console.WriteLine($"{user.UserPrincipalName}:\t\t{user.GivenName} {user.Surname}");
if (user.UserPrincipalName == "USER_WITH_PICTURE")
{
var graphUser = graphClient.Users[user.UserPrincipalName];
var graphPhoto = graphUser.Photo;
var photoInfo = await graphPhoto.Request().GetAsync(); // <= here the exceptions is thrown
Console.WriteLine($"{photoInfo.Id}:\t{photoInfo.Width}x{photoInfo.Height}");
var photoStream = await graphPhoto.Content.Request().GetAsync();
byte[] photoByte = new byte[photoStream.Length];
photoStream.Read(photoByte, 0, (int)photoStream.Length);
File.WriteAllBytes(@"D:\User.jpg", photoByte);
}
}
}
private static async Task<string> GetAppTokenAsync(string authority, string azureGraphAPI)
{
var authenticationContext = new AuthenticationContext(authority);
var clientCred = new ClientCredential(clientID, clientSecret);
var authenticationResult = await authenticationContext.AcquireTokenAsync(azureGraphAPI, clientCred);
return authenticationResult.AccessToken;
}
}
public class AuthenticationHelper : IAuthenticationProvider
{
public string AccessToken { get; set; }
public Task AuthenticateRequestAsync(HttpRequestMessage request)
{
request.Headers.Add("Authorization", "Bearer " + AccessToken);
return Task.FromResult(0);
}
}
我使用以下NuGet包:
<packages>
<package id="Microsoft.Data.Edm" version="5.7.0" targetFramework="net46" />
<package id="Microsoft.Data.OData" version="5.7.0" targetFramework="net46" />
<package id="Microsoft.Data.Services.Client" version="5.7.0" targetFramework="net46" />
<package id="Microsoft.Graph" version="1.0.1" targetFramework="net46" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="2.24.304111323" targetFramework="net46" />
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net46" />
<package id="Nito.AsyncEx" version="3.0.1" targetFramework="net46" />
<package id="System.Spatial" version="5.7.0" targetFramework="net46" />
</packages>
这是一个传递错误的示例请求(使用带有从上面的应用程序中读出的令牌的邮递员):
GET /v1.0/users/MY_USER_WITH_PHOTO/photo/ HTTP / 1.1
主持人:graph.microsoft.com
连接:保持活力
授权:bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1 ...
缓存控制:无缓存
用户代理:Mozilla / 5.0(Windows NT 6.3; WOW64)AppleWebKit / 537.36(KHTML,与Gecko一样)Chrome / 49.0.2623.112 Safari / 537.36
邮差 - 令牌:e756a8a3-22e2-d40c-8e52-15c4d1aa7468
接受: /
Accept-Encoding:gzip,deflate,sdch
Accept-Language:de,en-US; q = 0.8,en; q = 0.6
回复:
HTTP / 1.1 403禁止
缓存控制:私人
转移编码:分块
内容类型:application / json
服务器:Microsoft-IIS / 8.5
request-id:96e8dda8-2353-4891-8c42-99cfe7e22887
client-request-id:96e8dda8-2353-4891-8c42-99cfe7e22887
x-ms-ags-diagnostic:{&#34; ServerInfo&#34;:{&#34; DataCenter&#34;:&#34; North Europe&#34;,&#34; Slice&#34;:&#34 ; SliceA&#34;&#34; ScaleUnit&#34;:&#34; 001&#34;&#34;主机&#34;:&#34; AGSFE_IN_4&#34;&#34; ADSiteName&#34; :&#34; DUB&#34;}} 持续时间:1367.7691
X-Powered-By:ASP.NET
日期:太阳,2016年5月1日17:57:02 GMT
体:
{
&#34;错误&#34;:{
&#34;代码&#34;:&#34; ErrorAccessDenied&#34;,
&#34;消息&#34;:&#34;访问被拒绝。检查凭据,然后重试。&#34;, &#34; innerError&#34;:{
&#34; request-id&#34;:&#34; 96e8dda8-2353-4891-8c42-99cfe7e22887&#34;,
&#34; date&#34;:&#34; 2016-05-01T17:57:02&#34;
}
}
}
同样,如果我从请求中删除/photo
,我会毫无问题地获得所有常见的用户详细信息。
这是一个解密的访问令牌:
{
typ: "JWT",
alg: "RS256",
x5t: "MnC_VZcATfM5pOYiJHMba9goEKY",
kid: "MnC_VZcATfM5pOYiJHMba9goEKY"
}.
{
aud: "https://graph.microsoft.com",
iss: "https://sts.windows.net/11205e59-fa81-480f-b497-571579c5389a/",
iat: 1462795409,
nbf: 1462795409,
exp: 1462799309,
appid: "c34a87ef-352a-4af4-a166-eb7e521a0ec9",
appidacr: "1",
idp: "https://sts.windows.net/11205e59-fa81-480f-b497-571579c5389a/",
oid: "1db8c6b5-10ba-40ac-bbff-86ab440c4fd3",
roles: [
"Mail.ReadWrite",
"Device.ReadWrite.All",
"User.ReadWrite.All",
"Calendars.Read",
"Group.Read.All",
"Directory.ReadWrite.All",
"Contacts.ReadWrite",
"Group.ReadWrite.All",
"Directory.Read.All",
"User.Read.All",
"Mail.Read",
"Calendars.ReadWrite",
"Mail.Send",
"MailboxSettings.ReadWrite",
"Contacts.Read"
],
sub: "1db8c6b5-10ba-40ac-bbff-86ab440c4fd3",
tid: "11205e59-fa81-480f-b497-571579c5389a",
ver: "1.0"
}
答案 0 :(得分:0)
以防其他人在收到错误时读取此内容。我在创建自己的graphClient时遇到了同样的错误,我得到它的原因是由于使用非管理员帐户...
var users = await graphClient.Users.Request().Select().GetAsync();
使用非管理员帐户,您只能访问一些基本属性,如姓氏,名字等 - 这对我有用...
var users = await graphClient.Users.Request().Select("mail,givenName,surname").GetAsync();