Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Bearer Token for Kudu REST API calls #444

Merged
merged 2 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions AppService.Acmebot/Functions/SharedActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,22 +209,22 @@ public async Task Http01Precondition([ActivityTrigger] string id)

private async Task Http01Precondition_WebSite(ResourceIdentifier resourceId)
{
var webSite = _armClient.GetWebSiteResource(resourceId);
WebSiteResource webSite = await _armClient.GetWebSiteResource(resourceId).GetAsync();

WebSiteConfigResource config = await webSite.GetWebSiteConfig().GetAsync();

// 既に .well-known が仮想アプリケーションとして追加されているか確認
var virtualApplication = config.Data.VirtualApplications.FirstOrDefault(x => x.VirtualPath == "/.well-known");

if (virtualApplication != null)
if (virtualApplication is not null)
{
return;
}

// 発行プロファイルを取得
var credentials = await webSite.GetPublishingCredentialsAsync(WaitUntil.Completed);
// ファイル操作用の KuduClient を作成
var scmUri = webSite.Data.HostNameSslStates.First(x => x.HostType == AppServiceHostType.Repository);

var kuduClient = _kuduClientFactory.CreateClient(credentials.Value.Data.ScmUri);
var kuduClient = await _kuduClientFactory.CreateClientAsync(scmUri.Name);

try
{
Expand Down Expand Up @@ -253,22 +253,22 @@ private async Task Http01Precondition_WebSite(ResourceIdentifier resourceId)

private async Task Http01Precondition_WebSiteSlot(ResourceIdentifier resourceId)
{
var webSiteSlot = _armClient.GetWebSiteSlotResource(resourceId);
WebSiteSlotResource webSiteSlot = await _armClient.GetWebSiteSlotResource(resourceId).GetAsync();

WebSiteSlotConfigResource config = await webSiteSlot.GetWebSiteSlotConfig().GetAsync();

// 既に .well-known が仮想アプリケーションとして追加されているか確認
var virtualApplication = config.Data.VirtualApplications.FirstOrDefault(x => x.VirtualPath == "/.well-known");

if (virtualApplication != null)
if (virtualApplication is not null)
{
return;
}

// 発行プロファイルを取得
var credentials = await webSiteSlot.GetPublishingCredentialsSlotAsync(WaitUntil.Completed);
// ファイル操作用の KuduClient を作成
var scmUri = webSiteSlot.Data.HostNameSslStates.First(x => x.HostType == AppServiceHostType.Repository);

var kuduClient = _kuduClientFactory.CreateClient(credentials.Value.Data.ScmUri);
var kuduClient = await _kuduClientFactory.CreateClientAsync(scmUri.Name);

try
{
Expand Down Expand Up @@ -329,25 +329,25 @@ public async Task<IReadOnlyList<AcmeChallengeResult>> Http01Authorization([Activ
});
}

// 発行プロファイルを取得
PublishingUserData credentials;
// ファイル操作用の KuduClient を作成
HostNameSslState scmUri;

var resourceId = new ResourceIdentifier(id);

if (resourceId.ResourceType == WebSiteResource.ResourceType)
{
var webSite = _armClient.GetWebSiteResource(resourceId);
WebSiteResource webSite = await _armClient.GetWebSiteResource(resourceId).GetAsync();

credentials = (await webSite.GetPublishingCredentialsAsync(WaitUntil.Completed)).Value.Data;
scmUri = webSite.Data.HostNameSslStates.First(x => x.HostType == AppServiceHostType.Repository);
}
else
{
var webSiteSlot = _armClient.GetWebSiteSlotResource(resourceId);
WebSiteSlotResource webSiteSlot = await _armClient.GetWebSiteSlotResource(resourceId).GetAsync();

credentials = (await webSiteSlot.GetPublishingCredentialsSlotAsync(WaitUntil.Completed)).Value.Data;
scmUri = webSiteSlot.Data.HostNameSslStates.First(x => x.HostType == AppServiceHostType.Repository);
}

var kuduClient = _kuduClientFactory.CreateClient(credentials.ScmUri);
var kuduClient = await _kuduClientFactory.CreateClientAsync(scmUri.Name);

// Kudu API を使い、Answer 用のファイルを作成
foreach (var challengeResult in challengeResults)
Expand Down
20 changes: 6 additions & 14 deletions AppService.Acmebot/Internal/KuduClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Net;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
Expand All @@ -9,22 +8,16 @@ namespace AppService.Acmebot.Internal;

public class KuduClient
{
public KuduClient(HttpClient httpClient, Uri scmUri)
public KuduClient(HttpClient httpClient)
{
_httpClient = httpClient;
_scmHost = scmUri.Host;
_basicAuth = Convert.ToBase64String(Encoding.UTF8.GetBytes(scmUri.UserInfo));
}

private readonly HttpClient _httpClient;
private readonly string _scmHost;
private readonly string _basicAuth;

public async Task<bool> ExistsFileAsync(string filePath)
{
var request = new HttpRequestMessage(HttpMethod.Head, $"https://{_scmHost}/api/vfs/site/{filePath}");

request.Headers.Authorization = new AuthenticationHeaderValue("Basic", _basicAuth);
var request = new HttpRequestMessage(HttpMethod.Head, $"/api/vfs/site/{filePath}");

var response = await _httpClient.SendAsync(request);

Expand All @@ -43,15 +36,14 @@ public async Task<bool> ExistsFileAsync(string filePath)
return false;
}

public Task WriteFileAsync(string filePath, string content)
public async Task WriteFileAsync(string filePath, string content)
{
var request = new HttpRequestMessage(HttpMethod.Put, $"https://{_scmHost}/api/vfs/site/{filePath}");
var request = new HttpRequestMessage(HttpMethod.Put, $"/api/vfs/site/{filePath}");

request.Headers.Authorization = new AuthenticationHeaderValue("Basic", _basicAuth);
request.Headers.IfMatch.Add(EntityTagHeaderValue.Any);

request.Content = new StringContent(content, Encoding.UTF8);

return _httpClient.SendAsync(request);
await _httpClient.SendAsync(request);
}
}
21 changes: 18 additions & 3 deletions AppService.Acmebot/Internal/KuduClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;

using Azure.Core;

namespace AppService.Acmebot.Internal;

public class KuduClientFactory
{
public KuduClientFactory(IHttpClientFactory httpClientFactory)
public KuduClientFactory(IHttpClientFactory httpClientFactory, TokenCredential tokenCredential, AzureEnvironment environment)
{
_httpClientFactory = httpClientFactory;
_tokenCredential = tokenCredential;
_environment = environment;
}

private readonly IHttpClientFactory _httpClientFactory;
private readonly TokenCredential _tokenCredential;
private readonly AzureEnvironment _environment;

public KuduClient CreateClient(Uri scmUri)
public async Task<KuduClient> CreateClientAsync(string scmHost)
{
var httpClient = _httpClientFactory.CreateClient();

return new KuduClient(httpClient, scmUri);
var context = new TokenRequestContext(new[] { _environment.ResourceManager.DefaultScope }, null);
var accessToken = await _tokenCredential.GetTokenAsync(context, CancellationToken.None);

httpClient.BaseAddress = new Uri($"https://{scmHost}");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);

return new KuduClient(httpClient);
}
}