C# Azure 管理 REST API - 将证书绑定到应用服务自定义域

C# Azure Management REST API - Bind Certificate to App Service Custom Domain

我可以使用 Azure 管理 REST 创建一个自定义域 API,我可以创建一个应用服务托管证书,它与自定义域相关联(我认为)。也许不吧。但是,在我的应用服务的自定义域下,显示我需要添加绑定。

这是证书:

https://management.azure.com/subscriptions/xxx-xxx-479a-bb9f-4c7e01d9a379/resourceGroups/MyResourceGroup/providers/Microsoft.Web/sites/xxx20211028195113/hostNameBindings/my.site?api-version=2016-08-01

and 

https://management.azure.com/subscriptions/xxx-xxx-479a-bb9f-4c7e01d9a379/resourceGroups/MyResourceGroup/providers/Microsoft.Web/certificates/my.site?api-version=2021-02-01

我使用第一个端点创建自定义域,使用第二个端点创建证书。我不确定如何将证书绑定到自定义域。因为我在请求正文中包含了 serverFarm,所以我希望创建证书的调用能为我做这件事,但它没有用。

我想使用 Azure 管理 API 将证书绑定到自定义域。我怎样才能做到这一点?我应该使用哪个端点以及需要在请求正文中设置哪些值?

如有任何帮助,我们将不胜感激。谢谢。

有关我的完整代码参考,请在此处查看我的其他 post: C# .Net Azure Management REST API - Add App Service Managed Certificate - Response = Not Found

编辑:显示完整答案

using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyShoppingCart.Helpers.ManagementLibrarySample
{
    public class ManagementLibrarySample
    {

        static string _ClientId = Startup.StaticConfig.GetValue<string>("Azure:ClientId");
        static string _ClientKey = Startup.StaticConfig.GetValue<string>("Azure:ClientSecret");
        static string _TenantId = Startup.StaticConfig.GetValue<string>("Azure:TenantId");
        static string _SubscriptionId = Startup.StaticConfig.GetValue<string>("Azure:SubscriptionId");
        static string _ResourceGroupName = Startup.StaticConfig.GetValue<string>("Azure:ResourceGroupName");
        static string _AlternateResourceGroupName = Startup.StaticConfig.GetValue<string>("Azure:AlternateResourceGroupName");
        static string _AppName = Startup.StaticConfig.GetValue<string>("Azure:AppName");
        static string _AppServicePlanName = Startup.StaticConfig.GetValue<string>("Azure:AppServicePlanName");
        static Uri _baseURI = new Uri($"https://management.azure.com/");

        private static string GetAccessToken()
        {
            var context = new AuthenticationContext("https://login.windows.net/" + _TenantId);
            ClientCredential clientCredential = new ClientCredential(_ClientId, _ClientKey);
            var tokenResponse = context.AcquireTokenAsync(_baseURI.ToString(), clientCredential).Result;
            return tokenResponse.AccessToken;
        }

        public static async Task<bool> CreateCustomDomainAndCertificate(string sHostName)
        {
            bool ret = false;

            HttpResponseMessage responseMessage = await CreateCustomDomain(sHostName);

            if (responseMessage.IsSuccessStatusCode)
            {
                responseMessage = await CreateAppManagedCertificate(sHostName);

                /*
                     it can take a good 5 minutes to create the certificate
                     but you get the 202 status code right away.
                     
                     You cannot bind the certificate to the custom domain
                     name until after the certificate actually exists.
                 */

                if ((long)responseMessage.StatusCode == 202)// Accepted
                {
                    DateTime dtStart = DateTime.Now;

                    while ((long)responseMessage.StatusCode != 200 && DateTime.Now < dtStart.AddMinutes(10))
                    {//Wait until the certificate has been created, up to 10 minutes
                        Thread.Sleep(60000);//1 minute
                        responseMessage = await BindCertificateToCustomDomain(sHostName);
                    }
                    if ((long)responseMessage.StatusCode == 200)
                        ret = true;
                }
            }
            return ret;
        }

        private static async Task<HttpResponseMessage> CreateCustomDomain(string sHostName)
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken());
                string requestURl = _baseURI + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/sites/{_AppName}/hostNameBindings/{sHostName}?api-version=2016-08-01";
                string body = $"{{\"properties\": {{\"azureResourceName\": \"{_AppName}\"}}}}";

                var stringContent = new StringContent(body, Encoding.UTF8, "application/json");
                return await client.PutAsync(requestURl, stringContent);
            }
        }

        private static async Task<HttpResponseMessage> CreateAppManagedCertificate(string sHostName)
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken());
                string requestURl = _baseURI + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/certificates/{sHostName}?api-version=2021-02-01";
                string serverFarm = $"/subscriptions/{_SubscriptionId}/resourceGroups/{_AlternateResourceGroupName}/providers/Microsoft.Web/serverfarms/{_AppServicePlanName}";
                string body = $"{{\"location\": \"West US\", \"properties\": {{\"canonicalName\": \"{sHostName}\", \"hostNames\": [\"{sHostName}\"], \"serverFarmId\": \"{serverFarm}\"}}}}";

                var stringContent = new StringContent(body, Encoding.UTF8, "application/json");
                return await client.PutAsync(requestURl, stringContent);
            }

        }

        private static async Task<HttpResponseMessage> BindCertificateToCustomDomain(string sHostName)
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken());
                string requestURl = _baseURI + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/sites/{_AppName}?api-version=2016-08-01";
                string serverFarm = $"/subscriptions/{_SubscriptionId}/resourceGroups/{_AlternateResourceGroupName}/providers/Microsoft.Web/serverfarms/{_AppServicePlanName}";
                string body = $"{{\"location\": \"West US\", \"properties\": {{\"HostNameSslStates\": [ {{ \"SslState\" : \"1\", \"ToUpdate\" : \"True\", \"Name\": \"{sHostName}\"}}]}}, \"kind\": \"app\", \"location\": \"West US\", \"tags\" : {{\"hidden-related:{serverFarm}\": \"empty\"}}}}";

                var stringContent = new StringContent(body, Encoding.UTF8, "application/json");
                return await client.PutAsync(requestURl, stringContent);
            }
        }
    }
}

How can I use the Management API to secure the custom domain with the app service managed certificate? Thanks @David.Warwick for the confirmation, As we have discussed to achieve the above requirement we have to use the below Rest API .

您可以尝试使用 PUT 方法将 SSL 证书与自定义域绑定。

https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{snapshotName}?api-version={api-version} 

更多信息请参考这个