title: Azure Identity: Trying to get GetUserDelegationKey to work with an application Service Principal
body: <p>It's not a good sign when the method I'm asking about, <code>GetUserDelegationKey</code>, yields zero search results on SO. Good luck, me.</p>
  
  <p>I have a C# console app, .Net framework 4.8, using Azure.Storage.Blobs and Azure.Identity that will run on customer servers and access Azure blob storage to hold some stuff. I'm doing all of this with the library, not rolling my own REST. Built with VS2019, testing on Win10.</p>
  
  <p>The plan is to use a single Azure storage account that I own, and create one Container per customer project with per-customer credentials that permit them only their own container. Projects never ever talk to each other.</p>
  
  <p>I could set up credentials in the Azure portal by hand, but I am stubbornly trying to do this in software, where a simple project-management app connects as the project app's service principal (which I defined in Azure AD), creates the container, then creates the shared access signatures with a limited lifetime.</p>
  
  <p>The storage account name / container name / access signature would then be configured on the customer server. </p>
  
  <p>I'm having a terrible time.</p>
  
  <p>Note: this is using the newer BlobClient mechanisms, not the older CloudBlob stuff. Dunno if that matters.</p>
  
  <p>This is all documented <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal" rel="nofollow noreferrer">here at Microsoft</a>, and following even the simple example gets me the same failure.</p>
  
  <pre><code>using System;
  using Azure.Storage.Blobs;
  using Azure.Storage.Blobs.Models;
  using Azure.Identity;
  
  namespace Azure.Test
  {
      class Program
      {
          static void Main(string[] args)
          {
              var serviceClient = new BlobServiceClient(
                  new Uri("https://stevestorageacct.blob.core.windows.net"),
                  new DefaultAzureCredential(true));  // true=pop up login dlg
  
  /*BOOM*/    UserDelegationKey key = serviceClient.GetUserDelegationKey(
                  DateTimeOffset.UtcNow,
                  DateTimeOffset.UtcNow.AddDays(30));
  
              // use the key to create the signatures
          }
      }
  }
  </code></pre>
  
  <p>Even though this program couldn't be simpler, it fails every time with an XML error calling <code>GetUserDelegationKey</code></p>
  
  <pre><code>Unhandled Exception: Azure.RequestFailedException: The value for one of the XML nodes is not in the correct format.
  RequestId:c9b7d324-401e-0127-4a4c-1fe6ce000000
  Time:2020-05-01T00:06:21.3544489Z
  Status: 400 (The value for one of the XML nodes is not in the correct format.)
  ErrorCode: InvalidXmlNodeValue
  </code></pre>
  
  <p>The XML being sent is supposed to be super simple, I think just the start/end dates for validity, but I have no idea how to get to it to inspect, and <code>http</code> is forbidden for this kind of call, so no Wireshark.</p>
  
  <p>It also fails the same way when I use my application's service principal:</p>
  
  <pre><code>        static void Main(string[] args)
          {
              var tokenCredential = new ClientSecretCredential(
                  "xxxx-xxxx-xxxx-xxxxx",   // tenant ID
                  "yyyy-yyyy-yyyy-yyyyy,    // application ID
                  "**************");      // client secret
  
              var serviceClient = new BlobServiceClient(
                  new Uri("https://stevestorageacct.blob.core.windows.net"),
                  tokenCredential);
  
              UserDelegationKey key = serviceClient.GetUserDelegationKey(
                  DateTimeOffset.UtcNow,
                  DateTimeOffset.UtcNow.AddDays(30));
              // ALSO: boom
  </code></pre>
  
  <p>I'm really at a loss.</p>
  
  <p>I suppose I could try rolling my own REST and playing with it that way, but it doesn't feel like this should be necessary: this kind of error feels like a bug even if I'm doing something wrong. XML nodes?</p>
  
  <p>Also open to entirely different ways of approaching this problem if they are superior, but would like to at least find out why this is failing.</p>