question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

PKCE Code verifier is incorrect for Angular 12 production build

See original GitHub issue

Description

The bug was found in version angular-oauth2-oidc:12.0.2 in combination with Angular 12.2.1. It has only been reported since the update of angular version from 12.0.5 -> 12.2.1. (It is probably duplicate of #1117 )

ERROR

We are unable to login with PKCE Code.

POST https://login.microsoftonline.com/XXXX-YYYYY-42d2-a01a-13edff7f5fe7/oauth2/v2.0/token
[400 Bad Request]

---------

error   | "invalid_grant"
msg     | "AADSTS501481: The Code_Verifier does not match the code_challenge supplied in the authorization request."

Context & Approach

If we run the project with ng serve the SPA is able to connect to our Azure AD, also if we build the application with --configuration development. Only if we build the application in production mode, we are not able to login anymore. To further narrow down the problem, we turned off the optimization flags:

{
  // angular.json ...
  "configurations": {
    "fake-prod": {
      "buildOptimizer": false,
      "optimization": false
      // ...
    },
    "development": {
      "buildOptimizer": false,
      "optimization": false,
      "vendorChunk": true,
      "extractLicenses": false,
      "sourceMap": true,
      "namedChunks": true
    }
  }
}

With this setting you can log in again!

System information

Full system information
npx envinfo --system --binaries --browsers --npmPackages --duplicates --npmGlobalPackages
System:
OS: macOS 11.5.2
CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 31.76 MB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.15.3 - ~/.nvm/versions/node/v14.15.3/bin/node
Yarn: 1.22.10 - ~/.nvm/versions/node/v14.15.3/bin/yarn
npm: 7.16.0 - ~/.nvm/versions/node/v14.15.3/bin/npm
Browsers:
Chrome: 92.0.4515.159
Chrome Canary: 95.0.4612.2
Firefox: 90.0.2
Firefox Developer Edition: 92.0
Safari: 14.1.2
npmPackages:
@angular-devkit/build-angular: ~12.2.1 => 12.2.1
@angular-devkit/build-webpack: ^0.1202.1 => 0.1202.1
@angular-eslint/builder: ~12.2.1 => 12.2.2
@angular-eslint/eslint-plugin: ~12.2.1 => 12.2.2
@angular-eslint/eslint-plugin-template: ~12.2.1 => 12.2.2
@angular-eslint/schematics: ~12.2.1 => 12.2.2
@angular-eslint/template-parser: ~12.2.1 => 12.2.2
@angular/animations: ~12.2.1 => 12.2.1
@angular/animations/browser:  undefined ()
@angular/animations/browser/testing:  undefined ()
@angular/cdk: ~12.2.1 => 12.2.1
@angular/cdk/a11y:  undefined ()
@angular/cdk/accordion:  undefined ()
@angular/cdk/bidi:  undefined ()
@angular/cdk/clipboard:  undefined ()
@angular/cdk/coercion:  undefined ()
@angular/cdk/collections:  undefined ()
@angular/cdk/drag-drop:  undefined ()
@angular/cdk/keycodes:  undefined ()
@angular/cdk/layout:  undefined ()
@angular/cdk/observers:  undefined ()
@angular/cdk/overlay:  undefined ()
@angular/cdk/platform:  undefined ()
@angular/cdk/portal:  undefined ()
@angular/cdk/scrolling:  undefined ()
@angular/cdk/stepper:  undefined ()
@angular/cdk/table:  undefined ()
@angular/cdk/testing:  undefined ()
@angular/cdk/testing/protractor:  undefined ()
@angular/cdk/testing/selenium-webdriver:  undefined ()
@angular/cdk/testing/testbed:  undefined ()
@angular/cdk/text-field:  undefined ()
@angular/cdk/tree:  undefined ()
@angular/cli: ~12.2.1 => 12.2.1
@angular/common: ~12.2.1 => 12.2.1
@angular/common/http:  undefined ()
@angular/common/http/testing:  undefined ()
@angular/common/testing:  undefined ()
@angular/common/upgrade:  undefined ()
@angular/compiler: ~12.2.1 => 12.2.1
@angular/compiler-cli: ~12.2.1 => 12.2.1
@angular/compiler/testing:  undefined ()
@angular/core: ~12.2.1 => 12.2.1
@angular/core/testing:  undefined ()
@angular/flex-layout: ^12.0.0-beta.34 => 12.0.0-beta.34
@angular/flex-layout/core:  undefined ()
@angular/flex-layout/extended:  undefined ()
@angular/flex-layout/flex:  undefined ()
@angular/flex-layout/grid:  undefined ()
@angular/flex-layout/server:  undefined ()
@angular/forms: ~12.2.1 => 12.2.1
@angular/localize: ^12.2.1 => 12.2.1
@angular/localize/init:  undefined ()
@angular/platform-browser: ~12.2.1 => 12.2.1
@angular/platform-browser-dynamic: ~12.2.1 => 12.2.1
@angular/platform-browser-dynamic/testing:  undefined ()
@angular/platform-browser/animations:  undefined ()
@angular/platform-browser/testing:  undefined ()
@angular/router: ~12.2.1 => 12.2.1
@angular/router/testing:  undefined ()
@angular/router/upgrade:  undefined ()
@ngneat/until-destroy: ^8.0.4 => 8.0.4
@ngx-translate/core: ^13.0.0 => 13.0.0
@ngx-translate/http-loader: ^6.0.0 => 6.0.0
@ngxs/store: ^3.7.2 => 3.7.2
@ngxs/store/internals:  undefined ()
@ngxs/store/operators:  undefined ()
@types/jest: ^27.0.1 => 27.0.1
@types/node: ^12.11.1 => 12.20.15 (14.17.4)
@typescript-eslint/eslint-plugin: ^4.23.0 => 4.23.0
@typescript-eslint/parser: ^4.23.0 => 4.23.0 (3.10.1)
angular-oauth2-oidc: ^12.0.2 => 12.0.2
angular-svg-icon: ^12.0.0 => 12.0.0
compodoc: ^0.0.41 => 0.0.41
cypress: 7.6.0 => 7.6.0
eslint: ^7.26.0 => 7.29.0
eslint-config-prettier: ^8.3.0 => 8.3.0
eslint-plugin-prettier: ^3.4.0 => 3.4.0
fake-basic-project:  1.0.0
fake-project:  1.0.0
husky: ^7.0.0 => 7.0.0
jest: ^27.0.6 => 27.0.6
jest-preset-angular: ^9.0.6 => 9.0.6
jwt-decode: ^3.1.2 => 3.1.2
lib:  0.0.1
ng-mocks: ^12.4.0 => 12.4.0
ngx-permissions: ^8.1.1 => 8.1.1
normalize.css: ^8.0.1 => 8.0.1
prettier: ^2.3.2 => 2.3.2
prettier-eslint: ^12.0.0 => 12.0.0
rxjs: ~6.6.0 => 6.6.7 (7.3.0)
rxjs/ajax:  undefined ()
rxjs/fetch:  undefined ()
rxjs/internal-compatibility:  undefined ()
rxjs/operators:  undefined ()
rxjs/testing:  undefined ()
rxjs/webSocket:  undefined ()
sonarqube-scanner: ^2.8.1 => 2.8.1
start-server-and-test: ^1.12.5 => 1.12.5
tippy-headless:  0.1.0
tippy.js: ^6.3.1 => 6.3.1
tslib: ^2.1.0 => 2.3.0 (1.14.1, 2.1.0)
typescript: ~4.2.3 => 4.2.4 (4.3.5, 3.9.10, 2.2.0)
zone-mix:  undefined ()
zone-node:  undefined ()
zone-testing:  undefined ()
zone.js: ~0.11.4 => 0.11.4
zone.js/async-test:  undefined ()
zone.js/async-test.min:  undefined ()
zone.js/fake-async-test:  undefined ()
zone.js/fake-async-test.min:  undefined ()
zone.js/jasmine-patch:  undefined ()
zone.js/jasmine-patch.min:  undefined ()
zone.js/long-stack-trace-zone:  undefined ()
zone.js/long-stack-trace-zone.min:  undefined ()
zone.js/mocha-patch:  undefined ()
zone.js/mocha-patch.min:  undefined ()
zone.js/proxy:  undefined ()
zone.js/proxy.min:  undefined ()
zone.js/sync-test:  undefined ()
zone.js/sync-test.min:  undefined ()
zone.js/task-tracking:  undefined ()
zone.js/task-tracking.min:  undefined ()
zone.js/webapis-media-query:  undefined ()
zone.js/webapis-media-query.min:  undefined ()
zone.js/webapis-notification:  undefined ()
zone.js/webapis-notification.min:  undefined ()
zone.js/webapis-rtc-peer-connection:  undefined ()
zone.js/webapis-rtc-peer-connection.min:  undefined ()
zone.js/webapis-shadydom:  undefined ()
zone.js/webapis-shadydom.min:  undefined ()
zone.js/wtf:  undefined ()
zone.js/wtf.min:  undefined ()
zone.js/zone-bluebird:  undefined ()
zone.js/zone-bluebird.min:  undefined ()
zone.js/zone-error:  undefined ()
zone.js/zone-error.min:  undefined ()
zone.js/zone-legacy:  undefined ()
zone.js/zone-legacy.min:  undefined ()
zone.js/zone-patch-canvas:  undefined ()
zone.js/zone-patch-canvas.min:  undefined ()
zone.js/zone-patch-cordova:  undefined ()
zone.js/zone-patch-cordova.min:  undefined ()
zone.js/zone-patch-electron:  undefined ()
zone.js/zone-patch-electron.min:  undefined ()
zone.js/zone-patch-fetch:  undefined ()
zone.js/zone-patch-fetch.min:  undefined ()
zone.js/zone-patch-jsonp:  undefined ()
zone.js/zone-patch-jsonp.min:  undefined ()
zone.js/zone-patch-message-port:  undefined ()
zone.js/zone-patch-message-port.min:  undefined ()
zone.js/zone-patch-promise-test:  undefined ()
zone.js/zone-patch-promise-test.min:  undefined ()
zone.js/zone-patch-resize-observer:  undefined ()
zone.js/zone-patch-resize-observer.min:  undefined ()
zone.js/zone-patch-rxjs:  undefined ()
zone.js/zone-patch-rxjs-fake-async:  undefined ()
zone.js/zone-patch-rxjs-fake-async.min:  undefined ()
zone.js/zone-patch-rxjs.min:  undefined ()
zone.js/zone-patch-socket-io:  undefined ()
zone.js/zone-patch-socket-io.min:  undefined ()
zone.js/zone-patch-user-media:  undefined ()
zone.js/zone-patch-user-media.min:  undefined ()
npmGlobalPackages:
npm: 7.16.0
yarn: 1.22.10

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:8
  • Comments:16 (6 by maintainers)

github_iconTop GitHub Comments

9reactions
manfredsteyercommented, Aug 24, 2021

Awesome. Thanks for your help with this. Will release it as 12.1 very soon.

9reactions
manfredsteyercommented, Aug 24, 2021

Seems like the optimizer used by the CLI is destroying this. The lib for calculating sha256 is still using plain javascript and commonjs. Seems like the optimizer has issues with it.

I’ve completely switched it out now. Can you please give this version a try:

12.0.2-issue.1120.2

Best wishes, Manfred

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular 8 OAuth 2 Authorization Code Flow with PKCE
In this tutorial we will create an Angular application that authenticates using Authorization Code flow with PKCE. PKCE stands for Public ...
Read more >
Spotify PKCE code_verifier was incorrect - Stack Overflow
At this point, I try the fetch to the /api/token endpoint with the client_id, grant_type, the code I got from the url params,...
Read more >
Implement the OAuth 2.0 Authorization Code with PKCE Flow
That is no longer the case. PKCE works by having the app generate a random value at the beginning of the flow called...
Read more >
RFC 7636: Proof Key for Code Exchange by OAuth Public ...
This specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key for Code...
Read more >
Angular OAuth2 OIDC Configuration with IdentityServer4
But with the newest standards, that's not the case anymore. Now, it is a recommendation using the Authorization Code flow with PKCE (Proof...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found