panva / openid-client

High-Level OAuth 2 / OpenID Connect Client API for JavaScript Runtimes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DPoP proof to UserInfo Endpoint is missing 'ath' claim

hjmikkon opened this issue · comments

I'm trying to use the RP against an OP that enforces the use of DPoP access token. The OIDC SSO sequence is going as expected until the UserInfo-call: the OP doesn't accept the request because the mandatory 'ath' -claim is missing from the DPoP proof JWT.

By extracting the DPoP proof, I can see that only the following claims are included in the payload:

  • iat
  • jti
  • htu
  • htm

The section 4.2 of the DPoP RFC (9449) says that:

When the DPoP proof is used in conjunction with the presentation of an access token in protected resource access (see [Section 7](https://datatracker.ietf.org/doc/html/rfc9449#protected-resource-access)), the DPoP proof MUST also contain the following claim:

ath:
Hash of the access token. The value MUST be the result of a base64url encoding (as defined in [Section 2](https://rfc-editor.org/rfc/rfc7515#section-2) of [[RFC7515](https://datatracker.ietf.org/doc/html/rfc7515)]) the SHA-256 [[SHS](https://dx.doi.org/10.6028/NIST.FIPS.180-4)] hash of the ASCII encoding of the associated access token's value

For me it sounds like the bug on this library, or am I missing something?

I'm calling the userinfo in the following way (k contains asymmetric key):

      const tokenSet = await client!.callback(
        `${getDomain()}/auth/callback`,
        params, { state }, { 'DPoP': KeyObject.from(k.privateKey) }
      );
      const user = await client!.userinfo(tokenSet, { 'DPoP': KeyObject.from(k.privateKey) });

Hi @hjmikkon I am unable to reproduce and therefore confirm this report. There's a test confirming ath claim DPoP Proof presence with the userinfo method.

Hi @panva , thanks for your quick reply.

I'm seeing the following on the OP-side when receiving the userinfo request:

	Accept:[application/json]
	Accept-Encoding:[gzip, deflate, br]
	Authorization:[DPoP eyJraWQiOiJkZWZhdWx0UlNBU2lnbiIs...np0x9R5SSHUEM0RjIAq_TlJViYWByQ]
	Connection:[keep-alive]
	Content-Type:[null]
	dpop:[eyJhbGciOiJFUzM4NCIsInR5cCI6ImRwb3Arand0IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0zODQiLCJ4IjoiRllDTk9hSjNZVEVfMTJkNENVdmdWYlJnUVd5TUoyM1FoVEFZNVdGejBPd2FFRXktT1JzamJXd1VQTnNtSTd1WiIsInkiOiJnRDVXaTUyTTBXMGwzREpkSUp3a0ZveFB2MkVFVmlETVhXZXFTQ3FQOFNBY1ZtaW1uMFRQbkN2TWpaUmZkazBZIn19.eyJpYXQiOjE3MjU4ODAyOTUsImp0aSI6IklxNWFidTJ0Nkp5VGlubWVNSnBuOXJDSE9ERUtUQ0xxRzNZRzNESnNGUjgiLCJodHUiOiJodHRwczovL3Rlc3RvcC5mdW5ldC5maS9pZHAvcHJvZmlsZS9vaWRjL3VzZXJpbmZvIiwiaHRtIjoiR0VUIn0.zAJtdznRZuq1pfPlvLFX4feKk997zYMUOhwWcqYm0YIFe6kp2I9NitgSE69dv6pXtBbEEodCkKRg2TuQtU2L0sfUXeBd2zkeQQqyTxfKoL-nUIBh0Sf5S_S4T3CVZApU]

So it's clear that the DPoP proof payload doesn't have that access token hash, even though the library correctly has added it to the authorization header. Including the DPoP prefix.

I was using this fairly old example as a basis for my tests: https://github.com/franleplant/sso-with-openid

I updated the version in the package.json to 5.6.5 though, so I assume it's using a fresh version of the openid-client. But I may be wrong, this is more or less my first experiment with the Node.js stack..

-    "openid-client": "^4.2.0",
+    "openid-client": "^5.6.5",

Can you confirm the installed openid-client version e.g. with cat node_modules/openid-client/package.json | jq '.version'?

DPoP implementation supports ath since #407 which was included with release https://github.com/panva/node-openid-client/releases/tag/v4.9.0

That was it, the command you proposed is showing the ancient "4.2.0".

Thanks a lot, I'll find a way to upgrade the version into a fresh one. I assume it's then working as you said.