Azure Entra (AD) 用户创建的 REST 端点不起作用

问题描述 投票:0回答:1

我正在尝试创建 REST 端点,用于在 Azure Entra (AD) 中创建用户并验证用户是否存在于组中。这些端点将从自定义前端应用程序调用。

我尝试了以下代码,但不幸的是,我遇到了以下错误:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Identity.Client;
using Azure.Identity;




// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Entra_SPIKE.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class CreateUserController : Controller
    {
       
        


        private GraphServiceClient _graphServiceClient;

        public CreateUserController(GraphServiceClient graphServiceClient)
        {
            _graphServiceClient = graphServiceClient;
        }

        [HttpPost(Name = "PostCreateUser")]
        public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
        {
           
           try
            {
                var user = new User
                {
                    AccountEnabled = request.AccountEnabled,
                    DisplayName = request.DisplayName,
                    MailNickname = request.MailNickname,
                    UserPrincipalName = request.UserPrincipalName ,
                    PasswordProfile = new PasswordProfile
                    {
                        ForceChangePasswordNextSignIn = request.ForceChangePasswordNextSignIn,
                        Password = request.Password
                    }
                };

                // The client credentials flow requires that you request the
                // /.default scope, and pre-configure your permissions on the
                // app registration in Azure. An administrator must grant consent
                // to those permissions beforehand.
                var scopes = new[] { "https://graph.microsoft.com/.default" };

                // Values from app registration
                var tenantId = "MY-ID";

               // Values from app registration
                var clientId = "MY-ID";
                var clientSecret = "MY-Password";

                // using Azure.Identity;
                var options = new ClientSecretCredentialOptions
                {
                    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
                };

                // https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
                var clientSecretCredential = new ClientSecretCredential(
                    tenantId, clientId, clientSecret, options);

               var graphclient =  new GraphServiceClient(clientSecretCredential, scopes);


                var result = await graphclient.Users.PostAsync(user);


                return Ok("User created successfully");
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"An error occurred: {ex.Message}");
            }
        }




     
    }


    public class CreateUserRequest
    {
        public string DisplayName { get; set; }
        public string MailNickname { get; set; }
        public string UserPrincipalName { get; set; }
        public string Password { get; set; }
        public bool AccountEnabled { get; set; }
        public bool ForceChangePasswordNextSignIn { get; set; }

    }
}

System.InvalidOperationException:无法解析类型的服务 尝试激活时出现“Microsoft.Graph.GraphServiceClient” 'Entra_SPIKE.Controllers.CreateUserController'。在 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp,类型 type,类型 requiredBy,布尔值 isDefaultParameterRequired)

...

有人可以指导我吗?

c# microsoft-graph-api asp.net-core-webapi microsoft-graph-sdks azure-entra-id
1个回答
0
投票

首先,Azure AD 提供了多种身份验证流程,客户端凭据流程用于 Daemon 应用程序,该应用程序没有 UI 来让用户登录以获取身份验证,Daemon 应用程序只能代表应用程序进行身份验证本身。而如果应用程序是具有 UI 的 SPA 或 MVC 应用程序,以便它可以让用户登录,那么身份验证代码流可能是另一种选择,以便应用程序可以帮助代表用户进行身份验证。

回到您的场景,您有一个 API 项目,并且在控制器方法中您想通过 Graph SDK 调用 Graph API,因此您必须对

GraphServiceClient
进行身份验证。

通过 DI 使用

_graphServiceClient
始终用于身份验证代码流,通常与
builder.Services.AddRazorPages().AddMicrosoftIdentityUI();
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApp(builder.Configuration).EnableTokenAcquisitionToCallDownstreamApi(initialScopes).AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")).AddInMemoryTokenCaches();
一起使用。这需要用户登录。

但是Web API无法让用户登录,因此我们还有另一个选择,使用代表流程,这样我们仍然可以代表用户对GraphServiceClient进行身份验证。我们可以使用

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration).EnableTokenAcquisitionToCallDownstreamApi().AddMicrosoftGraph(builder.Configuration.GetSection("Graph")).AddInMemoryTokenCaches();
来代替。

如果我们不需要代表用户对 GraphServiceClient 进行身份验证,那么就像您已经拥有的用于客户端凭据流的

var graphclient =  new GraphServiceClient(clientSecretCredential, scopes);
一样,那么不需要依赖项注入,只需注释它们即可避免异常。顺便说一句,异常总是来自于没有
builder.service.xxx.AddMicrosoftGraph
。如果您添加该部分但没有用户登录信息,则会引发另一个异常。

之前在Web api项目中使用On-behalf-of flow进行了测试,如果需要,您可以检查一下。该示例使用了 Graph SDK v4.x。

© www.soinside.com 2019 - 2024. All rights reserved.