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

标签 azure ssl azure-web-app-service azure-custom-domain

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

enter image description here

这是证书:

enter image description here

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

我使用第一个端点创建自定义域,使用第二个端点创建证书。我不确定如何将证书绑定(bind)到自定义域。由于我在请求正文中包含了 serverFarm,因此我希望创建证书的调用能够为我完成此操作,但它不起作用。

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

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

有关我的完整代码引用,请参阅我的其他帖子: 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 证书与自定义域绑定(bind)。

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

欲了解更多信息,请参阅此SO THREAD

关于azure - C# Azure 管理 REST API - 将证书绑定(bind)到应用服务自定义域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70815827/

相关文章:

Azure EasyAuth : Getting Unauthorized error when try to login with a Microsoft account

SSL 访问 ejabberd API

ubuntu - dokku 和 digital ocean 的 ssl

git - 通过 GIT 将 Orchard.Source 部署到 Azure

c# - Umbraco 检查 Azure 上消失的索引

c# - Azure存储表逐行删除键

azure - azure 计算模拟器的域名或绑定(bind)名称

sql-server - 无法从 diff Web 角色中的本地数据库获取数据

Java 8 在下载 jar 时不会使用新的 Sectigo 交叉签名证书

azure - 如何在 Azure Web 应用程序中为容器设置 dns 选项