Skip to content

Using AzureCredentialsFactory.FromServicePrincipal with a certificate throws System.NullReferenceException #553

Open

Description

I created a console application using .NET framework 4.7.2 to connect to the Azure Resource Manager API using these nuget packages:

  • Microsoft.Azure.Management.ResourceManager.Fluent: v1.18.0 | download link
  • Microsoft.Azure.Management.Fluent: v1.18.0 | download link

This is the code:

using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent.Authentication;
using System;
using System.Security.Cryptography.X509Certificates;

namespace AzResourceManager
{
    class Program
    {
        static void Main(string[] args)
        {
            var clientId = "********-****-****-****-************";
            var subscriptionId = "********-****-****-****-************";
            var tenantId = "********-****-****-****-************"; 
            var cert = GetCertificate("********************************");

            var creds = new AzureCredentialsFactory().FromServicePrincipal(clientId, cert, tenantId, AzureEnvironment.AzureGlobalCloud);
            var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);

            foreach (var rGroup in azure.ResourceGroups.List())
            {
                Console.WriteLine(rGroup.Name);
            }
        }

        private static X509Certificate2 GetCertificate(string thumbPrint)
        {
            var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            certStore.Open(OpenFlags.ReadOnly);
            try
            {
                var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbPrint, false);
                if (certCollection.Count <= 0)
                    throw new InvalidOperationException("Unable to load certificate from store");
                return certCollection[0];
            }
            finally
            {
                certStore.Close();
            }
        }
    }
}

When the execution reaches this line

foreach (var rGroup in azure.ResourceGroups.List())

the application throws a System.NullReferenceException: 'Object reference not set to an instance of an object.'

this is the stack trace for that exception:

 
at Microsoft.Rest.Azure.Authentication.ClientAssertionCertificate.Sign(String message)\r\n   
at Microsoft.IdentityModel.Clients.ActiveDirectory.JsonWebToken.Sign(IClientAssertionCertificate credential) in c:\\workspace\\azure-activedirectory-library-for-dotnet-v3-master-VS2017\\src\\ADAL.PCL\\ClientCreds\\JsonWebToken.cs:line 100\r\n   
at Microsoft.IdentityModel.Clients.ActiveDirectory.ClientKey.AddToParameters(IDictionary`2 parameters) in c:\\workspace\\azure-activedirectory-library-for-dotnet-v3-master-VS2017\\src\\ADAL.PCL\\ClientCreds\\ClientKey.cs:line 127\r\n   
at Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenHandlerBase.<SendTokenRequestAsync>d__64.MoveNext() in c:\\workspace\\azure-activedirectory-library-for-dotnet-v3-master-VS2017\\src\\ADAL.PCL\\Flows\\AcquireTokenHandlerBase.cs:line 0\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n   

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   
at Microsoft.IdentityModel.Clients.ActiveDirectory.AcquireTokenHandlerBase.<RunAsync>d__55.MoveNext() in c:\\workspace\\azure-activedirectory-library-for-dotnet-v3-master-VS2017\\src\\ADAL.PCL\\Flows\\AcquireTokenHandlerBase.cs:line 198\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n   

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.<AcquireTokenForClientCommonAsync>d__49.MoveNext() in c:\\workspace\\azure-activedirectory-library-for-dotnet-v3-master-VS2017\\src\\ADAL.PCL\\AuthenticationContext.cs:line 541\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n   

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.<AcquireTokenAsync>d__27.MoveNext() in c:\\workspace\\azure-activedirectory-library-for-dotnet-v3-master-VS2017\\src\\ADAL.PCL\\AuthenticationContext.cs:line 239\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n   

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at Microsoft.Rest.Azure.Authentication.CertificateAuthenticationProvider.<AuthenticateAsync>d__3.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n   

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at Microsoft.Rest.Azure.Authentication.ApplicationTokenProvider.<LoginSilentAsync>d__33.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n   

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at Microsoft.Rest.Azure.Authentication.ApplicationTokenProvider.<LoginSilentAsync>d__24.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n  
 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   
at Microsoft.Azure.Management.ResourceManager.Fluent.Authentication.AzureCredentials.<ProcessHttpRequestAsync>d__24.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n
   
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n   at Microsoft.Azure.Management.ResourceManager.Fluent.ResourceGroupsOperations.<ListWithHttpMessagesAsync>d__11.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n 
  
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at Microsoft.Azure.Management.ResourceManager.Fluent.ResourceGroupsOperationsExtensions.<ListAsync>d__6.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown ---\r\n
   
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
at Microsoft.Azure.Management.ResourceManager.Fluent.Core.Extensions.Synchronize[TResult](Func`1 function)\r\n   
at Microsoft.Azure.Management.ResourceManager.Fluent.ResourceGroupsImpl.List()\r\n   
at AzResourceManager.Program.Main(String[] args) in D:\\Demos\\ARM\\AzResourceManager\\AzResourceManager\\Program.cs:line 27

If I use a secret instead of the certificate the code works correctly.

using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent.Authentication;
using System;
using System.Security.Cryptography.X509Certificates;

namespace AzResourceManager
{
    class Program
    {
        static void Main(string[] args)
        {
            var clientId = "********-****-****-****-************";
            var secret = "********-****-****-****-************";
            var subscriptionId = "********-****-****-****-************";
            var tenantId = "********-****-****-****-************"; 

            var creds = new AzureCredentialsFactory().FromServicePrincipal(clientId, secret, tenantId, AzureEnvironment.AzureGlobalCloud);            
            var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);

            foreach (var rGroup in azure.ResourceGroups.List())
            {
                Console.WriteLine(rGroup.Name);
            }
        }
    }
}

these are the packages installed: (packages.config)

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Azure.KeyVault" version="3.0.1" targetFramework="net472" />
  <package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net472" />
  <package id="Microsoft.Azure.KeyVault.WebKey" version="3.0.1" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.AppService.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Batch.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.BatchAI.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Cdn.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Compute.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.ContainerInstance.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.ContainerRegistry.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.ContainerService.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.CosmosDB.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Dns.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.EventHub.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Graph.RBAC.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.KeyVault.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Locks.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Monitor.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Msi.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Network.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Redis.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.ResourceManager.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Search.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.ServiceBus.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Sql.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.Storage.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Azure.Management.TrafficManager.Fluent" version="1.18.0" targetFramework="net472" />
  <package id="Microsoft.Data.Edm" version="5.8.2" targetFramework="net472" />
  <package id="Microsoft.Data.OData" version="5.8.2" targetFramework="net472" />
  <package id="Microsoft.Data.Services.Client" version="5.8.2" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.14.0" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Logging" version="1.1.2" targetFramework="net472" />
  <package id="Microsoft.IdentityModel.Tokens" version="5.1.2" targetFramework="net472" />
  <package id="Microsoft.Rest.ClientRuntime" version="2.3.17" targetFramework="net472" />
  <package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.18" targetFramework="net472" />
  <package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.3.4" targetFramework="net472" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net472" />
  <package id="System.ComponentModel.EventBasedAsync" version="4.0.11" targetFramework="net472" />
  <package id="System.Dynamic.Runtime" version="4.0.0" targetFramework="net472" />
  <package id="System.Linq.Queryable" version="4.0.0" targetFramework="net472" />
  <package id="System.Net.Requests" version="4.0.11" targetFramework="net472" />
  <package id="System.Spatial" version="5.8.2" targetFramework="net472" />
  <package id="WindowsAzure.Storage" version="8.1.4" targetFramework="net472" />
</packages>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

AuthorizationMgmtManagement plane SDK related issues.customer-reportedIssues that are reported by GitHub users external to the Azure organization.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions