Skip to content

Commit

Permalink
fix: interoperable audience array value for JWT Client auth assertion…
Browse files Browse the repository at this point in the history
…s (again)

- token endpoint is a SHOULD in all definitions
- issuer identifier is the defacto identifier that should be accepted too
- specific endpoint location is not defined anywhere
  • Loading branch information
panva committed Apr 14, 2022
1 parent 7a417c3 commit 96b367d
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 24 deletions.
13 changes: 1 addition & 12 deletions lib/helpers/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,8 @@ async function authFor(endpoint, { clientAssertionPayload } = {}) {
case 'private_key_jwt':
case 'client_secret_jwt': {
const timestamp = now();

const mTLS = endpoint === 'token' && this.tls_client_certificate_bound_access_tokens;
const audience = [
...new Set(
[
this.issuer.issuer,
this.issuer.token_endpoint,
this.issuer[`${endpoint}_endpoint`],
mTLS && this.issuer.mtls_endpoint_aliases
? this.issuer.mtls_endpoint_aliases.token_endpoint
: undefined,
].filter(Boolean),
),
...new Set([this.issuer.issuer, this.issuer.token_endpoint].filter(Boolean)),
];

const assertion = await clientAssertion.call(this, endpoint, {
Expand Down
23 changes: 11 additions & 12 deletions test/client/mtls.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,33 +102,32 @@ describe('mutual-TLS', () => {
token_endpoint_auth_signing_alg: 'HS256',
tls_client_certificate_bound_access_tokens: true,
});
this.jwtAuthClientNoSenderConstraining = new issuer.Client({
client_id: 'client',
client_secret: 'secret',
token_endpoint_auth_method: 'client_secret_jwt',
token_endpoint_auth_signing_alg: 'HS256',
tls_client_certificate_bound_access_tokens: false,
});
this.client[custom.http_options] = () => ({ key, cert });
});

it('uses the mtls endpoint alias for token endpoint when using jwt auth and tls certs', async function () {
it('uses the issuer identifier and token endpoint as private_key_jwt audiences', async function () {
let {
form: { client_assertion: jwt },
} = await clientHelpers.authFor.call(this.jwtAuthClient, 'token');
let { aud } = jose2.JWT.decode(jwt);
expect(aud).to.include('https://mtls.op.example.com/token');
expect(aud).to.include('https://op.example.com/token');
expect(aud).to.include('https://op.example.com');
expect(aud).to.deep.equal(['https://op.example.com', 'https://op.example.com/token']);
({
form: { client_assertion: jwt },
} = await clientHelpers.authFor.call(this.jwtAuthClient, 'introspection'));
({ aud } = jose2.JWT.decode(jwt));
expect(aud).not.to.include('https://mtls.op.example.com/token/introspect');
expect(aud).to.include('https://op.example.com/token/introspect');
expect(aud).to.include('https://op.example.com/token');
expect(aud).to.include('https://op.example.com');
expect(aud).to.deep.equal(['https://op.example.com', 'https://op.example.com/token']);
({
form: { client_assertion: jwt },
} = await clientHelpers.authFor.call(this.jwtAuthClient, 'revocation'));
({ aud } = jose2.JWT.decode(jwt));
expect(aud).not.to.include('https://mtls.op.example.com/token/revoke');
expect(aud).to.include('https://op.example.com/token/revoke');
expect(aud).to.include('https://op.example.com/token');
expect(aud).to.include('https://op.example.com');
expect(aud).to.deep.equal(['https://op.example.com', 'https://op.example.com/token']);
});

it('requires mTLS for userinfo when tls_client_certificate_bound_access_tokens is true', async function () {
Expand Down

0 comments on commit 96b367d

Please sign in to comment.