【问题标题】:Microsoft Graph API tests - get access on behalf of userMicrosoft Graph API 测试 - 代表用户获取访问权限
【发布时间】:2020-04-25 09:11:42
【问题描述】:

我有使用 Graph API (.Net Core 3.1) 为用户创建扩展的代码。我有这个代码的测试项目。但我需要以用户身份进行身份验证才能创建和使用 GraphServiceClient(用户具有全局管理员角色)。

我们的目标是拥有一个为User创建schemaExtension的工作代码。

现在,要创建扩展,客户端必须具有已授予门户中注册应用程序的委托权限 Directory.AccessAsUser.All。但由于这是一个委托权限,我需要以用户身份进行身份验证(在测试代码中)。所以我的选择是身份验证提供者:

  • 授权码提供者
  • 代表供应商
  • 交互式提供者

对于授权码提供者:

            List<string> scopes = new List<string> { "Directory.AccessAsUser.All" };

            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create(_appClientId.ToString())
                .WithRedirectUri(_redirectUri)
                .WithClientSecret(_appSecret) // or .WithCertificate(certificate)
                .Build();

            AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);
            _graphServiceClient = new GraphServiceClient(authProvider);

我得到一个例外:

Microsoft.Graph.Auth.AuthenticationException:代码:authenticationChallengeRequired

对于代表提供商:

            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create(_appClientId.ToString())
                .WithRedirectUri(_redirectUri)
                .WithClientSecret(_appSecret)
                .Build();

            OnBehalfOfProvider authProvider = new OnBehalfOfProvider(confidentialClientApplication, scopes);

            _graphServiceClient = new GraphServiceClient(authProvider);

我明白了

NullReferenceException

当我尝试实际创建架构时在这一行:

SchemaExtension extension = await _graphServiceClient .SchemaExtensions.Request().AddAsync(schemaExtension);

对于交互式提供商:

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

InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(publicClientApplication, scopes);

我明白了:

Microsoft.Identity.Client.MsalClientException :仅支持环回重定向 uri,但找到了 urn:ietf:wg:oauth:2.0:oob。在应用注册期间和创建 PublicClientApplication 对象时配置 http://localhosthttp://localhost:port

最后一个我完全不明白。那么如何才能使这种委托身份验证工作呢?

加法

这是创建扩展但不依赖于授权的代码:

  SchemaExtension schemaExtension = new SchemaExtension
  {
    Id = schemaName.Trim(),
    // Owner = _appClientId.ToString(),    
    Description = string.IsNullOrWhiteSpace(schemaDesc) ? string.Empty : schemaDesc.Trim(),
    TargetTypes = new List<string>
    {
      "User"
    },
    Properties = new List<ExtensionSchemaProperty>
    {
      new ExtensionSchemaProperty
      {
        Name = "isGlobalAdmin",
        Type = "Boolean"
      },
      new ExtensionSchemaProperty
      {
        Name = "isOrganizationAdmin",
        Type = "Boolean"
      }
    }
  };

  SchemaExtension extension = await GraphClient.SchemaExtensions.Request().AddAsync(schemaExtension); // GraphClient here === _graphServiceClient in the code above

【问题讨论】:

  • 可以分享一下代流的完整代码吗?包括 schemaExtension 对象的初始化?
  • 已添加,请看补充

标签: c# .net-core azure-active-directory microsoft-graph-api azure-ad-b2c


【解决方案1】:

根据我的研究,Microsoft Graph 的不同提供商使用不同的协议,并适用于不同的环境。更多详情请参考document

对于授权码提供者:

它使用OAuth 2.0 authorization code flow。正常情况下,我们用它来处理web app访问web api的情况。更多详情请参考doucment

对于交互式提供商

它使用OAuth 2.0 authorization code flow。通常,我们将它用于桌面应用程序(例如 WPF)。此外,请注意,当我们将提供程序与 MSAL.NET 一起使用时,we must register "http://localhost" as a Public client (mobile & desktop) redirect URI for your AD application。更多详情请参考document


更新

如果我们要使用Interactive provider调用Microsoft graph,请参考以下步骤

  1. 注册 Azure AD 应用程序
  2. 配置权限

  3. 代码

 static async Task Main(string[] args)
        {

            var clientId = "476944ed-e57c-4b2c-b18d-93b5dd5f1bca";
            string[] scopes = { "Directory.AccessAsUser.All" };
            #please provide the redirect url http://localhost when you create the client
            IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
            .Create(clientId)
            .WithRedirectUri("http://localhost") 
            .Build();

            InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(publicClientApplication, scopes);

            var graphClient = new GraphServiceClient(authProvider);
            var schemaExtension = new SchemaExtension
            {
                Id = "courses",
                Description = "Graph Learn training courses extensions",
                TargetTypes = new List<string>()
                    {
                        "Group"
                    },
                Properties = new List<ExtensionSchemaProperty>()
                    {
                        new ExtensionSchemaProperty
                        {
                            Name = "courseId",
                            Type = "Integer"
                        },
                        new ExtensionSchemaProperty
                        {
                            Name = "courseName",
                            Type = "String"
                        },
                        new ExtensionSchemaProperty
                        {
                            Name = "courseType",
                            Type = "String"
                        }
                    }
            };

            var result = await graphClient.SchemaExtensions.Request().AddAsync(schemaExtension);
            foreach (var type in result.TargetTypes) {
                Console.WriteLine(type);

            }

【讨论】:

  • 所有这些文档我都已经熟记了。这对我的案子有什么帮助?
  • @alvipeo 我已经更新了我的答案。请检查一下。
  • 非常感谢!马上试试。如果这行得通,我会喝一杯! :)
  • 好的,还没有。我尝试将此代码作为测试方法,并打开浏览器(!)进行用户身份验证。我成功通过身份验证,它把我重定向到http://localhost:63371/?code=OA...。此时测试完成异常 - Microsoft.Graph.ServiceException : Code: Service_InternalServerError。有没有办法在测试中模拟这种身份验证?或者只是从中创建一个测试?
  • @alvipeo 根据您的错误,您已完成 AD 身份验证并将请求发送到图形服务器,但图形服务器无法处理您的请求。更多详情请参考document。你能告诉我你想做什么吗?
猜你喜欢
  • 2017-05-19
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多