使用新版SDK在Azure App Service安装TLS证书遇404问题求助
(注:VB.NET或C#解答均可。)
使用新版Azure App Service SDK上传并安装第三方TLS证书遇到的问题
我在使用新版SDK安装已上传的证书时遇到问题,新版SDK未提供上传证书的方法,因此改用REST API完成上传操作。旧版SDK支持上传功能但已被弃用,技术迭代要求必须使用新版。
上传操作返回202状态码,看似成功,但Azure门户中并未显示该证书。推送站点数据更新时出现404错误:
状态:404(未找到)- 证书370A4097E85476AE65545702B410866882AD4541未找到。
该指纹与pfx证书的指纹完全匹配,确认这部分无问题。
上传代码
oApiCert = New Certificate With {.Location = oWebSiteData.Location.DisplayName} oApiCert.Properties.CanonicalName = sCanonicalName oApiCert.Properties.ServerFarmId = oWebSiteData.AppServicePlanId.ToString oApiCert.Properties.Password = My.Resources.PfxPassword oApiCert.Properties.PfxBlob = oX509Cert.Export(X509ContentType.Pfx, My.Resources.PfxPassword) oApiCert.Properties.HostNames.AddRange(oX509Cert.SanHostNames) sJsonContent = JsonConvert.SerializeObject(oApiCert, JsonHelper.DefaultSerializationSettings) oContent = New StringContent(sJsonContent, Encoding.UTF8, "application/json") oClient = New HttpClient oClient.DefaultRequestHeaders.Add("Authorization", "Bearer " & oToken.Token) oClient.BaseAddress = New Uri(My.Resources.ManagementEndpoint) oResponse = Await oClient.PutAsync(sUrl, oContent) oResponse.EnsureSuccessStatusCode()
更新代码
oSslStates = oWebSiteData.HostNameSslStates oHostNames = oHostNames.Intersect(oWebSiteData.HostNames).ToList oHostNames.ForEach(Sub(HostName) oSslState = oSslStates.FirstOrDefault(Function(SslState) SslState.Name = HostName) If oSslState Is Nothing Then oSslState = New HostNameSslState With {.Name = HostName} oSslStates.Add(oSslState) End If oSslState.Thumbprint = BinaryData.FromObjectAsJson(oX509Cert.Thumbprint) oSslState.SslState = HostNameBindingSslState.SniEnabled oSslState.ToUpdate = True End Sub) oSitePatch = New SitePatchInfo For Each oState In oSslStates If oState.ToUpdate Then oSitePatch.HostNameSslStates.Add(oState) End If Next oWebSiteResource.Update(oSitePatch) ' <-- 404 here '
这段代码移植自LetsEncrypt-SiteExtension包,原库依赖旧版SDK。
新版SDK的文档和代码示例极为匮乏,我并非一定要按当前方式实现,只要方案可行即可。请问如何使用新版SDK在Azure App Service上上传并安装第三方TLS证书?有人成功实现过吗?
完整代码
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Net.Http Imports System.Security.Cryptography.X509Certificates Imports System.Text Imports System.Threading.Tasks Imports Azure Imports Azure.Core Imports Azure.Identity Imports Azure.ResourceManager Imports Azure.ResourceManager.AppService Imports Azure.ResourceManager.AppService.Models Imports Azure.ResourceManager.Resources Imports Matrix.Common Imports Newtonsoft.Json Imports Nito.AsyncEx Friend Module Program Friend Sub Main() AsyncContext.Run(Async Function() Await UploadCert() End Function) End Sub Private Async Function UploadCert() As Task Dim oWebSiteResponse As Response(Of WebSiteResource) Dim oWebSiteResource As WebSiteResource Dim oResourceGroup As ResourceGroupResource Dim sCanonicalName As String Dim oSubscription As SubscriptionResource Dim oWebSiteData As WebSiteData Dim sJsonContent As String Dim oCredential As ClientSecretCredential Dim oSslStates As IList(Of HostNameSslState) Dim oHostNames As List(Of String) Dim aHostNames As String() Dim oSitePatch As SitePatchInfo Dim oArmClient As ArmClient Dim oResponse As HttpResponseMessage Dim oX509Cert As X509Certificate2 Dim oSslState As HostNameSslState Dim aScopeUrl As String() Dim sCertName As String Dim oContext As TokenRequestContext Dim oContent As StringContent Dim oApiCert As Certificate Dim oClient As HttpClient Dim oToken As AccessToken Dim oUrl As List(Of String) Dim sUrl As String oX509Cert = Utils.GetCertificate(My.Resources.CertFriendlyName) aHostNames = My.Resources.HostNames.Split(",", StringSplitOptions.RemoveEmptyEntries) oHostNames = New List(Of String)(aHostNames) sCanonicalName = oHostNames.First sCertName = $"{sCanonicalName}-{oX509Cert.Thumbprint}" oUrl = New List(Of String) From { "subscriptions", My.Resources.SubscriptionId, "resourceGroups", My.Resources.ResourceGroup, "providers", "Microsoft.Web", "certificates", sCertName } sUrl = String.Join("/", oUrl) sUrl = $"/{sUrl}?api-version=2022-03-01" oCredential = New ClientSecretCredential(My.Resources.TenantId, My.Resources.ClientId, My.Resources.ClientSecret) oArmClient = New ArmClient(oCredential) oSubscription = Await oArmClient.GetDefaultSubscriptionAsync oResourceGroup = Await oSubscription.GetResourceGroups.GetAsync(My.Resources.ResourceGroup) oWebSiteResponse = Await oResourceGroup.GetWebSiteAsync(My.Resources.AppServiceName) oWebSiteResource = oWebSiteResponse.Value oWebSiteData = oWebSiteResource.Data aScopeUrl = New String() {$"{My.Resources.ManagementEndpoint}.default"} oContext = New TokenRequestContext(aScopeUrl) oToken = Await oCredential.GetTokenAsync(oContext) oApiCert = New Certificate With {.Location = oWebSiteData.Location.DisplayName} oApiCert.Properties.CanonicalName = sCanonicalName oApiCert.Properties.ServerFarmId = oWebSiteData.AppServicePlanId.ToString oApiCert.Properties.Password = My.Resources.PfxPassword oApiCert.Properties.PfxBlob = oX509Cert.Export(X509ContentType.Pfx, My.Resources.PfxPassword) oApiCert.Properties.HostNames.AddRange(oX509Cert.SanHostNames) sJsonContent = JsonConvert.SerializeObject(oApiCert, JsonHelper.DefaultSerializationSettings) oContent = New StringContent(sJsonContent, Encoding.UTF8, "application/json") oClient = New HttpClient oClient.DefaultRequestHeaders.Add("Authorization", "Bearer " & oToken.Token) oClient.BaseAddress = New Uri(My.Resources.ManagementEndpoint) oResponse = Await oClient.PutAsync(sUrl, oContent) oResponse.EnsureSuccessStatusCode() oSslStates = oWebSiteData.HostNameSslStates oHostNames = oHostNames.Intersect(oWebSiteData.HostNames).ToList oHostNames.ForEach(Sub(HostName) oSslState = oSslStates.FirstOrDefault(Function(SslState) SslState.Name = HostName) If oSslState Is Nothing Then oSslState = New HostNameSslState With {.Name = HostName} oSslStates.Add(oSslState) End If oSslState.Thumbprint = BinaryData.FromObjectAsJson(oX509Cert.Thumbprint) oSslState.SslState = HostNameBindingSslState.SniEnabled oSslState.ToUpdate = True End Sub) oSitePatch = New SitePatchInfo For Each oState In oSslStates If oState.ToUpdate Then oSitePatch.HostNameSslStates.Add(oState) End If Next oWebSiteResource.Update(oSitePatch) ' <-- 404 here ' End Function End Module
内容的提问来源于Stack Exchange,提问作者InteXX
相关产品推荐
相关产品推荐

