繁体   English   中英

C# 的图表 API:401 - 未经授权:由于凭据无效,访问被拒绝。 在 /planner/plans

[英]Graph API for C#: 401 - Unauthorized: Access is denied due to invalid credentials. on /planner/plans

我正在使用 Graph API。 我没有太多这方面的经验。 我正在创建一个应用程序以将计划添加到现有组中。

所以,我已经注册了一个具有此权限的应用程序(您可以看到这些是委托权限):

在此处输入图像描述

然后,我编写了这段代码来使用这个端点 /planner/plans 添加一个新的 Planner(你会看到我正在使用一个令牌)。

var configAuthority = "https://login.microsoftonline.com/8318d89e-e4db-471e-85da-b34ae833813f";
            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                                  .Create(ConfigurationParameters.ClientID)
                                  .WithTenantId(ConfigurationParameters.TenantID)
                                  .WithClientSecret(ConfigurationParameters.ClientSecret)
                                  .WithAuthority(new Uri(configAuthority))
                                  .Build();
            ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
            string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
            AuthenticationResult accessToken = confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync().Result;
            GraphServiceClient graphClient = new GraphServiceClient(authProvider);
            List<HeaderOption> requestHeaders = new List<HeaderOption>() {
                            new HeaderOption("Authorization", "Bearer " + accessToken.AccessToken)
                };
            var existingsplanners = graphClient
                                        .Groups[createPlannerForGroupRequest.GroupId.ToString()]
                                        .Planner
                                        .Plans.
                                        Request(requestHeaders)
                                        .GetAsync()
                                        .Result;
            var planner = graphClient
                        .Groups[createPlannerForGroupRequest.GroupId.ToString()]
                        .Planner
                        .Plans
                        .Request(requestHeaders)
                        .AddAsync(new PlannerPlan { 
                            Title = createPlannerForGroupRequest.Name,
                            Owner = createPlannerForGroupRequest.GroupId.ToString(),
                            ODataType = null,
                        }).Result;

两个请求的结果是相同的。

Code: UnknownError
Message: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} 
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>401 - Unauthorized: Access is denied due to invalid credentials.</h2>
  <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>
 </fieldset></div>
</div>
</body>
</html>

Inner error:
    AdditionalData:
    request-id: 19c09b10-1694-4201-85a9-ba3639e1dba5
    date: 2020-06-03T07:29:59
ClientRequestId: 19c09b10-1694-4201-85a9-ba3639e1dba5

如您所见,即使它是 Azure AD 上的委派权限,也存在权限问题。 我应该等24小时吗? 我应该更改令牌请求者方法而不是使用 AcquireTokenForClient 吗?

相同的方法适用于 Graph Explorer。 为现有组创建 Team 实例可以正常工作。

谢谢!

似乎您在代码中使用了客户端凭据授予流程,但图表 api 仅支持委派权限。 所以我们需要使用授权码授权流程或用户名/密码授权流程。 (顺便说一下,我们推荐授权码流而不是用户名/密码流)

有关授权代码流程,请参阅本教程,其中包含代码示例。

IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithRedirectUri(redirectUri)
    .WithClientSecret(clientSecret) // or .WithCertificate(certificate)
    .Build();

AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);

对于用户名/密码流程,您可以参考本教程以及其中的代码示例。

IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
            .Create(clientId)
            .WithTenantId(tenantID)
            .Build();

UsernamePasswordProvider authProvider = new UsernamePasswordProvider(publicClientApplication, scopes);

GraphServiceClient graphClient = new GraphServiceClient(authProvider);

User me = await graphClient.Me.Request()
                .WithUsernamePassword(email, password)
                .GetAsync();

更新:

您可以按照以下步骤进行一些更改,然后您不需要在代码中提供 client_secret 并且它也不会显示错误消息The request body must contain the following parameter: 'client_assertion' or 'client_secret'

  1. Go 到您在 azure 广告中注册的应用程序,然后单击“身份验证”->“添加平台”->“移动和桌面应用程序”。 在此处输入图像描述

  2. 选择第一个作为“重定向 URI”。 在此处输入图像描述

  3. 向下滚动并检查此配置是否为“是”(如果“否”,请将其更改为“是”),然后单击“保存”。 在此处输入图像描述

我已尝试使用证书创建身份验证。 首先,在应用程序注册中应用该配置(仅具有应用程序权限)并从您之前共享的链接中阅读一些指南后,我从 /Groups 获得并且它有效。 之后,向 /Groups/{XXX-XX}/Planner/Plans 创建了一个新请求并收到权限错误。 创建证书的方法来自这个链接: https://laurakokkarinen.com/authenticating-to-office-365-apis-with-a-certificate-step-by-step/这是获取所有组的代码。

var url = "https://graph.microsoft.com";
var auth = new Authorization(ConfigurationParameters.TenantID, 
                            ConfigurationParameters.ClientID,
                            "‎34 64 03 a4 9c ad xx xx xx xx xx xx xx xx xx xx xx xx xx xx", 
                            @"C:\temp\Certificate.pfx", 
                            "Come up with something secure!");
var accessToken =  auth.GetAccessTokenAsync(url).Result;
using (var httpClient = new HttpClient())
{

    httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
    string urlReq = "https://graph.microsoft.com/v1.0/groups/" + createPlannerForGroupRequest.GroupId.ToString() + "";
    var response = httpClient.GetAsync(urlReq);
    Stream receiveStream = response.Result.Content.ReadAsStreamAsync().Result;
    StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
    var r = readStream.ReadToEnd();
    return r;
 }

那行得通,我可以阅读要求的组,但是当我应用此端点时:

string urlReq = "https://graph.microsoft.com/v1.0/groups/" + createPlannerForGroupRequest.GroupId.ToString() + "/planner/plans";

我收到此错误消息:

{
  "error": {
    "code": "UnknownError",
    "message": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"/>\r\n<title>403 - Forbidden: Access is denied.</title>\r\n<style type=\"text/css\">\r\n<!--\r\nbody{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}\r\nfieldset{padding:0 15px 10px 15px;} \r\nh1{font-size:2.4em;margin:0;color:#FFF;}\r\nh2{font-size:1.7em;margin:0;color:#CC0000;} \r\nh3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} \r\n#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:\"trebuchet MS\", Verdana, sans-serif;color:#FFF;\r\nbackground-color:#555555;}\r\n#content{margin:0 0 0 2%;position:relative;}\r\n.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}\r\n-->\r\n</style>\r\n</head>\r\n<body>\r\n<div id=\"header\"><h1>Server Error</h1></div>\r\n<div id=\"content\">\r\n <div class=\"content-container\"><fieldset>\r\n  <h2>403 - Forbidden: Access is denied.</h2>\r\n  <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>\r\n </fieldset></div>\r\n</div>\r\n</body>\r\n</html>\r\n",
    "innerError": {
      "request-id": "3ddaf510-6c16-403e-a365-4f2c6f27032c",
      "date": "2020-06-05T06:08:24"
    }
  }
}

我想我这次明白了:),但我得到了一个错误。 我现在使用这种方式来获取令牌:

IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
            .Create(ConfigurationParameters.ClientID)
            .WithTenantId(ConfigurationParameters.TenantID)
            .Build();
            string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
            UsernamePasswordProvider authProvider = new UsernamePasswordProvider(publicClientApplication, scopes);
            var token = authProvider.ClientApplication.AcquireTokenByUsernamePassword(scopes,u,               ToSecureString(p));
            var t = token.ExecuteAsync().Result;

没有证书,只有用户名和密码。 我收到此错误消息:

{"error":"invalid_client","error_description":"AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.\r\nTrace ID: d75e8aea-4d4e-4d34-a015-efd1d7f53600\r\nCorrelation ID: c3a5e38f-91e3-488c-91de-e850eef19219\r\nTimestamp: 2020-06-05 07:20:38Z","error_codes":[7000218],"timestamp":"2020-06-05 07:20:38Z","trace_id":"d75e8aea-4d4e-4d34-a015-efd1d7f53600","correlation_id":"c3a5e38f-91e3-488c-91de-e850eef19219","error_uri":"https://login.microsoftonline.com/error?code=7000218"

API 中的权限被委派给 Group.ReadAll 和 WriteAll。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM