【问题标题】:How can I programmatically create an Microsoft MsaAppId and MsaAppPassword via the Microsoft Graph API?如何通过 Microsoft Graph API 以编程方式创建 Microsoft MsaAppId 和 MsaAppPassword?
【发布时间】:2018-08-28 14:26:36
【问题描述】:

为了自动部署聊天机器人应用程序,我需要创建 MsaAppId 和 MsaAppPassword 并将它们传递给 Azure SDK 或 ARM 模板。

如果我去https://apps.dev.microsoft.com/#/appList 并在那里创建应用程序,我可以获得 MsaAppId 和 MsaAppPassword 并使用它。但是,当我尝试自动化部署过程时,这当然没有用。

我找到了两岁的question here on Stack Overflow,这也差不多。我能从中得到的是,我应该通过 Microsoft Graph API 来做到这一点。但是我不知道 API 是否发生了变化,但我无法重现被选为正确的答案中报告的相同结果。

当我使用类似的有效负载向同一端点发出请求时,这就是我从 API 得到的结果:

值得一提的是,我正在使用个人 @outlook.com 帐户登录 Azure。

我仍然不确定 MSA 应用和我的 Azure 帐户应用之间的关联。如果登录我的 azure 帐户并转到我的应用程序,我看不到通过 https://apps.dev.microsoft.com/#/appList 创建的应用程序(当然,我使用的是同一个帐户)。

【问题讨论】:

  • 您能否详细说明“当我尝试自动化部署过程时,这当然没有用”?您通常不需要为每个部署提供新的 App ID。
  • @MarcLaFleur 当每个部署用于不同的应用程序时,您需要。我正在尝试创建一个 Web API,它能够创建和部署一个新的聊天机器人应用程序并将 DirectLine 密码返回给调用者。因此,如果我调用 API 10 次,我将部署 10 个不同的机器人应用程序。
  • 我仍然不确定我是否理解您为什么需要不同的 App ID。生成多个 App ID 还意味着您需要多个用户同意流程(可能还有管理员同意流程,具体取决于您需要的范围)。
  • @MarcLaFleur 我不确定您是否熟悉 Azure 机器人服务。但是每个新的聊天机器人应用程序都需要唯一的 MsaAppId 和与之关联的 MsaAppPassword。因此,对于我的应用程序要部署的每个新聊天机器人,我需要提供不同的 MsaAppId 和不同的 MsaAppPassword。我需要将此信息放在我的应用程序代码的 Web.config 中。
  • Bot 注册包括一些超出传统应用注册的附加位。我怀疑你在这里寻找的是Microsoft.Azure.Management.BotService。此 SDK 处理 bot 服务的管理端(与 Graph 或 Bot SDK 中的客户端相反)。

标签: azure azure-active-directory microsoft-graph-api


【解决方案1】:

您仍然无法自动创建聚合的 AD 应用程序主体。这是当前 Graph v2 API 的限制,请阅读更多 herehere。 你必须在Application Registration Portal注册他们

【讨论】:

    【解决方案2】:

    我使用以下内容来创建应用注册,它适用于创建机器人。它是在 azure AD 中创建的,并且需要应用注册并具有对所有应用程序的读写权限。

        using System;
        using System.Threading.Tasks;
        using Microsoft.Azure.ActiveDirectory.GraphClient;
        using Microsoft.IdentityModel.Clients.ActiveDirectory;
        
        namespace AzureRegistration
        {
            /// <summary>
            /// Manages app registrations in azure AD
            /// </summary>
            public class AzureAppRegistrationManager
            {
                private const string resource = "https://graph.windows.net/";
        
        
                private readonly string tenant;
        
                private readonly string appId;
        
                private readonly string appPassword;
                
                private string AuthString => $"https://login.microsoftonline.com/{tenant}";
        
                private string appToken = null;
        
                /// <summary>
                /// Connects to the tenant using the client credentials passed in.
                /// Requires users to have permissions to create app registrations.
                /// </summary>
                /// <param name="tenant">Tenant name</param>
                /// <param name="appId">App ID</param>
                /// <param name="appPassword">App Password</param>
                public AzureAppRegistrationManager(string tenant, string appId, string appPassword)
                {
                    this.tenant = tenant;
                    this.appId = appId;
                    this.appPassword = appPassword;
                }
        
                /// <summary>
                /// Creates an app registration with a password that expires in 2 years. Returns the app ID of the application
                /// </summary>
                /// <param name="appPassword">Value of the password</param>
                /// <param name="appTitle">App display name</param>
                /// <param name="identifierUrl">The identifier URL. This must be unique across the azure AD</param>
                /// <param name="availableToOtherTenants">True to be available to other tenants</param>
                /// <returns>Returns the app ID</returns>
                public async Task<string> CreateAppRegistrationAsync(string appPassword, string appTitle, string identifierUrl, bool availableToOtherTenants = false)
                {
                    IApplication app = new Application()
                    {
                        DisplayName = appTitle,
                        AvailableToOtherTenants = availableToOtherTenants,
                        IdentifierUris = new string[] { identifierUrl }
                    };
        
                    PasswordCredential password = new PasswordCredential()
                    {
                        StartDate = DateTime.UtcNow,
                        EndDate = DateTimeOffset.UtcNow.AddYears(2).DateTime,
                        Value = appPassword
                    };
        
                    app.PasswordCredentials.Add(password);
        
                    ActiveDirectoryClient client = GetActiveDirectoryClientAsApplication();
        
                    await client.Applications.AddApplicationAsync(app);
        
                    return app.AppId;
                }
        
                /// <summary>
                /// Deletes the app with the app ID
                /// </summary>
                /// <param name="appId">Application ID to be deleted</param>
                /// <returns></returns>
                public async Task DeleteAppRegistrationAsync(string appId)
                {
                    ActiveDirectoryClient client = GetActiveDirectoryClientAsApplication();
        
                    try
                    {
                        IApplication app = await client.Applications.Where(a => a.AppId == appId).ExecuteSingleAsync();
                        await app.DeleteAsync();
                    }
                    catch (NullReferenceException) { }
                }
                
                private ActiveDirectoryClient GetActiveDirectoryClientAsApplication()
                {
                    Uri servicePointUri = new Uri(resource);
                    Uri serviceRoot = new Uri(servicePointUri, tenant);
                    ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, GetTokenForApplicationAsync);
                        //async () => await GetTokenForApplication());
                    return activeDirectoryClient;
                }
        
                /// <summary>
                /// Get Token for Application.
                /// </summary>
                /// <returns>Token for application.</returns>
                private async Task<string> GetTokenForApplicationAsync()
                {
                    if (appToken == null)
                    {
                        AuthenticationContext authenticationContext = new AuthenticationContext(
                            AuthString,
                            false);
        
                        // Configuration for OAuth client credentials 
                        if (string.IsNullOrEmpty(appPassword))
                        {
                            Console.WriteLine(
                                "Client secret not set. Please follow the steps in the README to generate a client secret.");
                        }
                        else
                        {
                            ClientCredential clientCred = new ClientCredential(
                                appId,
                                appPassword);
                            AuthenticationResult authenticationResult =
                                await authenticationContext.AcquireTokenAsync(resource, clientCred);
                            appToken = authenticationResult.AccessToken;
                        }
                    }
                    return appToken;
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多