Skip to content

Commit 8878ab9

Browse files
authored
Switch logstream command to use Bearer token when basic auth is not allowed. (#3342)
1 parent fd56265 commit 8878ab9

File tree

4 files changed

+69
-3
lines changed

4 files changed

+69
-3
lines changed

src/Azure.Functions.Cli/Actions/AzureActions/LogStreamAction.cs

+21-3
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,29 @@ public override async Task RunAsync()
5151
throw new CliException("Log stream is not currently supported in Linux Consumption Apps. " +
5252
"Please use --browser to open Azure Application Insights Live Stream in the Azure portal.");
5353
}
54-
var basicHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{functionApp.PublishingUserName}:{functionApp.PublishingPassword}"));
55-
54+
5655
using (var client = new HttpClient())
5756
{
58-
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicHeaderValue);
57+
var isBasicAuthAllowed = true;
58+
try
59+
{
60+
isBasicAuthAllowed = await AzureHelper.IsBasicAuthAllowedForSCM(functionApp, AccessToken, ManagementURL);
61+
}
62+
catch (Exception)
63+
{
64+
// ignore: We don't want to fail the command on basic auth check. There is extremely low likelihood of getting the exception here.
65+
}
66+
67+
if (isBasicAuthAllowed)
68+
{
69+
var basicHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{functionApp.PublishingUserName}:{functionApp.PublishingPassword}"));
70+
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicHeaderValue);
71+
}
72+
else
73+
{
74+
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
75+
}
76+
5977
client.DefaultRequestHeaders.Add("User-Agent", Constants.CliUserAgent);
6078
var response = await client.GetStreamAsync(new Uri($"https://{functionApp.ScmUri}/api/logstream/application"));
6179
using (var reader = new StreamReader(response))

src/Azure.Functions.Cli/Arm/ArmUriTemplates.cs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ internal static class ArmUriTemplates
1010
public const string WebsitesApiVersion = "2015-08-01";
1111
public const string SyncTriggersApiVersion = "2016-08-01";
1212
public const string ArgApiVersion = "2019-04-01";
13+
public const string BasicAuthCheckApiVersion = "2022-03-01";
1314

1415
public const string ArgUri = "providers/Microsoft.ResourceGraph/resources";
1516

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using static NuGet.Client.ManagedCodeConventions;
8+
9+
namespace Azure.Functions.Cli.Arm.Models
10+
{
11+
class BasicAuthCheckResponse
12+
{
13+
[JsonProperty(PropertyName = "id")]
14+
public string Id { get; set; }
15+
16+
[JsonProperty(PropertyName = "name")]
17+
public string ResourceName { get; set; }
18+
19+
[JsonProperty(PropertyName = "type")]
20+
public string ResourceType { get; set; }
21+
22+
[JsonProperty(PropertyName = "location")]
23+
public string Location { get; set; }
24+
25+
[JsonProperty(PropertyName = "properties")]
26+
public BasicAuthCheckResponseProperties Properties { get; set; }
27+
}
28+
29+
class BasicAuthCheckResponseProperties
30+
{
31+
[JsonProperty(PropertyName = "allow")]
32+
public bool Allow { get; set; }
33+
}
34+
}

src/Azure.Functions.Cli/Helpers/AzureHelper.cs

+13
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ internal static async Task<string> GetResourceIDFromArg(IEnumerable<string> subI
106106
?? throw new CliException("Error finding the Azure Resource information.");
107107
}
108108

109+
internal static async Task<bool> IsBasicAuthAllowedForSCM(Site functionApp, string accessToken, string managementURL)
110+
{
111+
var url = new Uri($"{managementURL}{functionApp.SiteId}/basicPublishingCredentialsPolicies/scm?api-version={ArmUriTemplates.BasicAuthCheckApiVersion}");
112+
113+
var response = await ArmClient.HttpInvoke(HttpMethod.Get, url, accessToken);
114+
response.EnsureSuccessStatusCode();
115+
116+
var result = await response.Content.ReadAsStringAsync();
117+
var basicAuthResponse = JsonConvert.DeserializeObject<BasicAuthCheckResponse>(result);
118+
119+
return basicAuthResponse.Properties.Allow;
120+
}
121+
109122
internal static ArmResourceId ParseResourceId(string resourceId)
110123
{
111124
if (string.IsNullOrEmpty(resourceId))

0 commit comments

Comments
 (0)