Azure-sdk-for-net: Cannot auth with certificate to azure when targeting .NET 4.5.2

Created on 15 Jun 2017  路  4Comments  路  Source: Azure/azure-sdk-for-net

I cannot authenticate to Azure using certificates available in release 1.1.0
public AzureCredentials FromServicePrincipal(string clientId, string certificatePath, string certificatePassword, string tenantId, AzureEnvironment environment) when my project is targeting 4.5.2, but it works when I target the NetCore framework.

This fails with the exception System.Security.Cryptography.CryptographicException: The specified network password is not correct, when actually trying to auth ( e.g. calling azureClient.TrafficManagerProfiles.GetByResourceGroup where azureClient is of type IAzure).

The only difference I saw was that for 4.5.2 Microsoft.IdentityModel.Clients.ActiveDirectory is set to 2.28.3 while for NetCore is set to 3.13.9. This is referenced by Microsoft.Rest.ClientRuntime.Azure. Authentication 2.3.0.

Most helpful comment

For who is having this issue, here is a sample implementation of the CustomAzureCredentials which you can use it then to pass it to the Azure Client like this:

            this.azureClient = Azure
                .Configure()
                .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
                .Authenticate(credentials)
                .WithSubscription(subscriptionId);

CustomAzureCredentials implementation:

    internal class CustomAzureCredentials : AzureCredentials
    {
        private readonly X509Certificate2 certificate;
        private readonly string clientId;

        public CustomAzureCredentials(string appId, string tenantId, X509Certificate2 certificate, AzureEnvironment azureEnvironment)
            : base((ServicePrincipalLoginInformation)null, tenantId, azureEnvironment)
        {
            this.certificate = certificate;
            this.clientId = appId;
        }

        public override async Task ProcessHttpRequestAsync(HttpRequestMessage message, CancellationToken cancelToken)
        {
            var assertionCertificate = new ClientAssertionCertificate(this.clientId, certificate);
            ServiceClientCredentials scc = await ApplicationTokenProvider.LoginSilentWithCertificateAsync(this.TenantId, assertionCertificate, TokenCache.DefaultShared);

            await scc.ProcessHttpRequestAsync(message, cancelToken);
        }
    }

All 4 comments

For now you will need to have a custom implementation of AzureCredentials and overload ProcessHttpRequestAsync

We should add an overload which will take X509Certificate2 as a parameter.

For who is having this issue, here is a sample implementation of the CustomAzureCredentials which you can use it then to pass it to the Azure Client like this:

            this.azureClient = Azure
                .Configure()
                .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
                .Authenticate(credentials)
                .WithSubscription(subscriptionId);

CustomAzureCredentials implementation:

    internal class CustomAzureCredentials : AzureCredentials
    {
        private readonly X509Certificate2 certificate;
        private readonly string clientId;

        public CustomAzureCredentials(string appId, string tenantId, X509Certificate2 certificate, AzureEnvironment azureEnvironment)
            : base((ServicePrincipalLoginInformation)null, tenantId, azureEnvironment)
        {
            this.certificate = certificate;
            this.clientId = appId;
        }

        public override async Task ProcessHttpRequestAsync(HttpRequestMessage message, CancellationToken cancelToken)
        {
            var assertionCertificate = new ClientAssertionCertificate(this.clientId, certificate);
            ServiceClientCredentials scc = await ApplicationTokenProvider.LoginSilentWithCertificateAsync(this.TenantId, assertionCertificate, TokenCache.DefaultShared);

            await scc.ProcessHttpRequestAsync(message, cancelToken);
        }
    }

Fixed for .Net 452 in Fluent v1.1.3

Was this page helpful?
0 / 5 - 0 ratings