title: Is Active Directory not supporting Authorization Code Flow with PKCE?
body: <p>I tried to use the currently recommended Authorization Code Flow with PKCE to gather an access token from Active Directory. The client will be a public Angular SPA which is the reason for the chosen flow.</p>
  
  <p>Gathering the openid-configuration form AD as well as the Authorization Code for a user worked well.
  But I fail requesting the access token from the following endpoint:</p>
  
  <pre><code>https://login.microsoftonline.com/{tenantId}/oauth2/token.
  </code></pre>
  
  <p>I tried to reconstruct the request in Postman:</p>
  
  <pre><code>POST /7e8c2868-7490-4dd7-82b7-f5ec29222d30/oauth2/token HTTP/1.1
  Host: login.microsoftonline.com
  Accept: application/json, text/plain, */*
  Content-Type: application/x-www-form-urlencoded
  Cache-Control: no-cache
  
  grant_type=authorization_code
  code=...
  code_verifier=...
  client_id=...
  redirect_uri=...
  </code></pre>
  
  <p>...and end up with the following message:</p>
  
  <pre><code>{
    "error": "invalid_client",
    "error_description": "AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.\r\nTrace ID: ed0413ad-89f1-4a2b-8d68-e23498701800\r\nCorrelation ID: deb53b0d-5398-4f72-a9a5-6c0863547b99\r\nTimestamp: 2020-03-06 09:30:36Z",
    "error_codes": [
      7000218
    ],
    "timestamp": "2020-03-06 09:30:36Z",
    "trace_id": "ed0413ad-89f1-4a2b-8d68-e23498701800",
    "correlation_id": "deb53b0d-5398-4f72-a9a5-6c0863547b99",
    "error_uri": "https://login.microsoftonline.com/error?code=7000218"
  }
  </code></pre>
  
  <p>This seems odd, since the official specification of the Authentication Flow with PKCE doesn't require a client_secret or client_assertion. This is only required for the default Authentication Flow.</p>
  
  <p>Is there something wrong with the AD implementation or have i misconfigured it?</p>
  
  <p>The manifest of the web client looks like this:</p>
  
  <pre><code>{
    "id": "...",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": null, 
    "addIns": [],
    "allowPublicClient": true,
    "appId": "...",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "...",
    "groupMembershipClaims": null,
    "identifierUris": [],
    "informationalUrls": {
      "termsOfService": null,
      "support": null,
      "privacy": null,
      "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": null,
    "name": "...",
    "oauth2AllowIdTokenImplicitFlow": false,
    "oauth2AllowImplicitFlow": false,
    "oauth2Permissions": [],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
      "countriesBlockedForMinors": [],
      "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [],
    "preAuthorizedApplications": [],
    "publisherDomain": "...",
    "replyUrlsWithType": [
      {
          "url": "http://localhost:4200",
          "type": "Web"
      }
    ],
    "requiredResourceAccess": [
      {
          "resourceAppId": "00000003-0000-0000-c000-000000000000",
          "resourceAccess": [
              {
                  "id": "...",
                  "type": "Scope"
              }
          ]
      }
    ],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADMyOrg",
    "tags": [],
    "tokenEncryptionKeyId": null
  }
  </code></pre>
  
  <p>And my application is registered as a public app in AD.</p>
  
  <p>The Authentication request that was sent prior to that looked like this:</p>
  
  <pre><code>GET /.../oauth2/authorize
    response_type=code
    &amp;client_id=...
    &amp;state=...
    &amp;redirect_uri=http%3A%2F%2Flocalhost%3A4200
    &amp;scope=openid%20user_impersonation%20offline_access
    &amp;code_challenge=...
    &amp;code_challenge_method=...
    &amp;nonce=...
  
  Host: login.microsoftonline.com
  </code></pre>