为了自动部署chatbot应用程序,我需要创建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 Apps和我的Azure帐户应用之间的相关性。如果登录到我的azure帐户并转到我的应用程序,我看不到通过https://apps.dev.microsoft.com/#/appList创建的应用程序(当然,我使用的是同一帐户)。
答案 0 :(得分:2)
您仍然无法自动创建聚合AD应用程序主体。这是当前Graph v2 API的限制,请阅读更多here和here。 您必须在Application Registration Portal
中进行注册答案 1 :(得分:0)
我使用以下内容创建应用注册,并且可以与创建漫游器一起使用。不过,它是在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;
}
}
}