1

我可以使用 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 将证书绑定到自定义域。我怎样才能做到这一点?我应该使用哪个端点以及需要在请求正文中设置哪些值?

任何帮助,将不胜感激。谢谢。

有关我的完整代码参考,请参阅我的另一篇文章: 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);
            }
        }
    }
}
4

1 回答 1

1

如何使用 Management API 通过应用服务托管证书保护自定义域?感谢@David.Warwick 的确认,正如我们所讨论的要实现上述要求,我们必须使用下面的 Rest API。

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

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

有关更多信息,请参阅此SO THREAD

于 2022-01-23T17:25:13.617 回答