Skip to content

Commit

Permalink
refactor(DPoP): omit sending the dpop-nonce header if the existing on…
Browse files Browse the repository at this point in the history
…e used is fresh
  • Loading branch information
panva committed Feb 13, 2024
1 parent d1f7d73 commit 4d635e2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
16 changes: 11 additions & 5 deletions lib/helpers/validate_dpop.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ export default async (ctx, accessToken) => {
if (typeof requireNonce !== 'boolean') {
throw new Error('features.dPoP.requireNonce must return a boolean');
}

if (DPoPNonces) {
ctx.set('DPoP-Nonce', DPoPNonces.nextNonce());
} else if (requireNonce) {
if (requireNonce && !DPoPNonces) {
throw new Error('features.dPoP.nonceSecret configuration is missing');
}

Expand All @@ -70,6 +67,8 @@ export default async (ctx, accessToken) => {
if (diff > DPOP_OK_WINDOW) {
throw new InvalidDpopProof('DPoP proof iat is not recent enough');
}
} else if (!DPoPNonces) {
throw new InvalidDpopProof('DPoP nonces are not supported');
}

if (payload.htm !== ctx.method) {
Expand Down Expand Up @@ -103,14 +102,21 @@ export default async (ctx, accessToken) => {
throw new InvalidDpopProof('invalid DPoP key binding', err.message);
}

const nextNonce = DPoPNonces?.nextNonce();
if (!payload.nonce && requireNonce) {
ctx.set('DPoP-Nonce', nextNonce);
throw new UseDpopNonce('nonce is required in the DPoP proof');
}

if (payload.nonce && (!DPoPNonces || !DPoPNonces.checkNonce(payload.nonce))) {
if (payload.nonce && !DPoPNonces.checkNonce(payload.nonce)) {
ctx.set('DPoP-Nonce', nextNonce);
throw new UseDpopNonce('invalid nonce in DPoP proof');
}

if (payload.nonce !== nextNonce) {
ctx.set('DPoP-Nonce', nextNonce);
}

const thumbprint = await calculateJwkThumbprint(protectedHeader.jwk);

const result = { thumbprint, jti: payload.jti, iat: payload.iat };
Expand Down
16 changes: 14 additions & 2 deletions test/dpop/dpop.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,11 @@ describe('features.dPoP', () => {
})
.set('DPoP', await DPoP(this.keypair, `${this.provider.issuer}${this.suitePath('/request')}`, 'POST', nonce))
.type('form')
.expect(201);
.expect(201)
.expect((response) => {
// because the sent one is fresh
expect(response.headers).not.to.have.property('dpop-nonce');
});
});

it('@ userinfo', async function () {
Expand All @@ -1012,6 +1016,10 @@ describe('features.dPoP', () => {
.send({ grant_type: 'client_credentials' })
.set('DPoP', await DPoP(this.keypair, `${this.provider.issuer}${this.suitePath('/me')}`, 'GET', nonce, 'foo'))
.expect(401)
.expect((response) => {
// because the sent one is fresh
expect(response.headers).not.to.have.property('dpop-nonce');
})
.expect({ error: 'invalid_token', error_description: 'invalid token provided' });
});

Expand All @@ -1031,7 +1039,11 @@ describe('features.dPoP', () => {
.send({ grant_type: 'client_credentials' })
.set('DPoP', await DPoP(this.keypair, `${this.provider.issuer}${this.suitePath('/token')}`, 'POST', nonce))
.type('form')
.expect(200);
.expect(200)
.expect((response) => {
// because the sent one is fresh
expect(response.headers).not.to.have.property('dpop-nonce');
});
});
});
});

0 comments on commit 4d635e2

Please sign in to comment.