title: Azure B2C Custom Extension Attribute Not Updating
body: <p>I am trying to add/update a value to a custom extension attribute for a user in Azure AD B2C.  The attribute is an AccountNumber with the type as string.  I have two different Azure environments I'm working out of.  One is for my local/staging environments, and the other is client's production Azure environment.  My local and staging are working fine, but I cannot seem to get this attribute to get updated through the production instance, which is leading me to think I'm missing some sort of permission/configuration within the Azure instance itself rather than code, but let's see.</p>
  
  <p>Here are the steps I've taken in Azure:</p>
  
  <ol>
  <li>Within the B2C I've setup my application.  For the API Access section I have 2 selections
  
  <ul>
  <li>Acquire an id_token for users (openid)</li>
  <li>Acquire a refresh_token for users (offline_access)</li>
  </ul></li>
  <li>I have two user flows both of which are returning AccountNumber as a claim.</li>
  <li><p>Within App registrations (NOT legacy), I've added my application as well.  It does have a warning about not being supported yet in B2C, but I have this in my staging instance as well.  I have the following for API Permissions that have been selected for this application.  I've gone back and forth adding the offline_access, openid, and profile. (All are uder Microsoft Graph Delegated)</p>
  
  <ul>
  <li>User.Read</li>
  <li>User.ReadWrite</li>
  <li>offline_access</li>
  <li>openid</li>
  <li>profile</li>
  </ul></li>
  <li><p>In App registrations/Authentication tab I've enabled implicit grant flow and checked both Access tokens and ID tokens</p></li>
  <li>Ive taken the b2c-extensions-app app ID and saved it within my code for using to update the extensions attribute (dashes removed)</li>
  </ol>
  
  <p>Web.config</p>
  
  <pre><code>&lt;add key="ida:NonAdminScopes" value="User.Read User.ReadWrite" /&gt;
  &lt;add key="ida:AdminScopes" value="Directory.AccessAsUser.All User.ReadWrite.All Group.ReadWrite.All" /&gt;
  </code></pre>
  
  <p>Here is where I'm building and making the request. Yes, I realize I'm doing this a more manual way, but I'm also working with Sitecore which has required me to keep some older dlls and this is where I've landed after days of frustration. </p>
  
  <pre><code>private async Task&lt;string&gt; SendGraphPatchRequest(string json, string objectId)
          {
              var graphEndpoint = new Uri(string.Format("https://graph.microsoft.com/v1.0/{0}/users/{1}", Tenant, objectId));
              HttpResponseMessage response;
  
              using (var httpClient = new HttpClient { BaseAddress = graphEndpoint })
              {
                  using (var requestMessage = new HttpRequestMessage(new HttpMethod("PATCH"), graphEndpoint))
                  {
                      var token = await GetOrCreateAccessToken();
  
                      requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
                      if (!string.IsNullOrEmpty(json))
                      {
                          requestMessage.Content = new StringContent(json, Encoding.UTF8, "application/json");
                      }
  
                      response = await httpClient.SendAsync(requestMessage).ConfigureAwait(continueOnCapturedContext: false);
  
                      if (!response.IsSuccessStatusCode)
                      {
                          string error = await response.Content.ReadAsStringAsync();
                          Logger.Error(string.Format("Error -&gt; RequestMessage: {0}", error));
  
                          object formatted = JsonConvert.DeserializeObject(error);
                          throw new WebException("Error Calling the Graph API: \n" + JsonConvert.SerializeObject(formatted, Formatting.Indented));
                      }
                  }
              }
  
              return response.Content.ReadAsStringAsync().Result;
          }
  </code></pre>
  
  <p>The line that is creating the access token does use ClientCredentials</p>
  
  <pre><code>_accessToken = await _authContext.AcquireTokenAsync("https://graph.microsoft.com/", _credentials);
  </code></pre>
  
  <p>An example of the request body content</p>
  
  <pre><code>{"extension_[extensionAppId]_AccountNumber":"123456"}
  </code></pre>
  
  <p>And when I try to make this request with Postman (I had a line of code where I was logging the token that gets created from the above code snippet - not sure if that will actually work or not), here is the response I get back:</p>
  
  <pre><code>{
    "error": {
      "code": "Authorization_RequestDenied",
      "message": "Insufficient privileges to complete the operation.",
      "innerError": {
        "request-id": "####",
        "date": "2019-08-21T15:06:45"
      }
    }
  }
  </code></pre>