Search code examples
azureazure-web-app-serviceazure-sdk-.netazure-fluent-api

How to get Azure App Service TLS configuration information using Azure .NET Fluent SDK?


I'm trying to get TLS version configured on an App Service (WebApp) using Azure Fluent .NET SDK in C#.

I used the following code to get WebApp information using LINQPad :

    // Nuget : Install-Package Microsoft.Azure.Management.AppService.Fluent -Version 1.24.0
    // using Microsoft.Azure.Management.AppService.Fluent;
    // using Microsoft.Azure.Management.AppService.Fluent.Models;
    // using Microsoft.Azure.Management.ResourceManager.Fluent;

    // Using a Service Principal created on my Azure Subscription
    var clientId = "<service_principal_clientid_with_readaccess>";
    var tenantId = "<my_azuread_tenantid>";

    var credentials = SdkContext
        .AzureCredentialsFactory
        .FromServicePrincipal(clientId, 
            Util.GetPassword("azure-cli-secret"), // LINQPad helper, replace if needed 
            tenantId, 
            AzureEnvironment.AzureGlobalCloud);

    // Get one web app with TLS 1.2 configured
    var webApp = AppServiceManager
        .Authenticate(credentials, "<azure_subscription_id>")
        .WebApps
        .GetById("<webapp_resource_id>");

    // Dump object returned, LINQPad helper method
    webApp.Dump();

When dumping object model returned, I don't find the TLS information returned anywhere. That something that should be available since it's returned by the REST API.

Analysis

You can see that the information is available using https://resources.azure.com or directly on this endpoint :

https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{appServiceName}/config?api-version=2018-02-01

That give you the following output (properties list shortened here) :

{
  "value": [
    {
      "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{appServiceName}/config/web",
      "name": "{appServiceName}",
      "type": "Microsoft.Web/sites/config",
      "location": "West Europe",
      "properties": {
        "http20Enabled": false,
        "minTlsVersion": "1.2",
        "ftpsState": "AllAllowed",
        "reservedInstanceCount": 0,
        "preWarmedInstanceCount": null,
        "healthCheckPath": null
      }
    }
  ],
  "nextLink": null,
  "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{appServiceName}/config"
}

Then I looked at the SDK code source available here : https://github.com/Azure/azure-libraries-for-net. I found that the TLS version should be available in the SiteConfig object. This SiteConfig appears to be located inside the Inner property.

When looking at the object dump we got with LINQPad, we can see that the SiteConfig object isn't populated :

enter image description here

When debugging this code, with a break point, we can see that the information seems available internally but it's not mapped to the SiteConfig property available publicly inside Inner property.

Debug session screenshot where we see the non-public member _siteConfig populated :

enter image description here

Is it a bug or I missed something ?
Any ideas ?


Solution

  • Yes. If you use this way, the siteConfig will always return null. It is by design. If you want to get the related information, you can use the following method which would correct configuration as per your requirement:

    AzureCredentials credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(
                clientId,
                clientSecret,
                tenantId,
                AzureEnvironment.AzureGlobalCloud).WithDefaultSubscription(subscriptionId);
    
    RestClient restClient = RestClient
                .Configure()
                .WithEnvironment(AzureEnvironment.AzureGlobalCloud)
                .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
                .WithCredentials(credentials)
                .Build();
    
    ResourceManagementClient resourceManagementClient = new ResourceManagementClient(restClient);
    WebSiteManagementClient webSiteManagementClient = new WebSiteManagementClient(restClient);
    webSiteManagementClient.SubscriptionId = subscriptionId;
    var configs = webSiteManagementClient.WebApps.GetConfigurationAsync("<rg name>", "<app name>").Result;
    var minTls = configs.MinTlsVersion;
    Console.WriteLine(minTls);