Skip to content

Commit e5efa5c

Browse files
committed
refactor!: userinfo requests with bearer tokens will now fail if they also include DPoP
1 parent 1093f6b commit e5efa5c

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

lib/actions/userinfo.js

+4
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ export default [
110110

111111
ctx.assert(unique, new InvalidToken('DPoP proof JWT Replay detected'));
112112
}
113+
114+
if (!accessToken.jkt) {
115+
throw new InvalidToken('access token is not sender-constrained but proof of possession was provided');
116+
}
113117
}
114118

115119
if (accessToken.jkt && (!dPoP || accessToken.jkt !== dPoP.thumbprint)) {

test/dpop/dpop.test.js

+17
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,23 @@ describe('features.dPoP', () => {
314314
}
315315
});
316316

317+
it("doesn't allow Bearer tokens to be passed with DPoP scheme", async function () {
318+
const at = new this.provider.AccessToken({
319+
accountId: this.loggedInAccountId,
320+
grantId: this.getGrantId(),
321+
client: await this.provider.Client.find('client'),
322+
scope: 'openid',
323+
});
324+
325+
const dpop = await at.save();
326+
const proof = await DPoP(this.keypair, `${this.provider.issuer}${this.suitePath('/me')}`, 'GET', undefined, dpop);
327+
328+
await this.agent.get('/me')
329+
.set('Authorization', `DPoP ${dpop}`)
330+
.set('DPoP', proof)
331+
.expect(this.failWith(401, 'invalid_token', 'invalid token provided', undefined, 'DPoP'));
332+
});
333+
317334
it('acts like an RS checking the DPoP proof and thumbprint now', async function () {
318335
const at = new this.provider.AccessToken({
319336
accountId: this.loggedInAccountId,

0 commit comments

Comments
 (0)