Skip to content

Commit

Permalink
fix: interoperable audience array value for JWT Client auth assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Mar 24, 2021
1 parent 0e2c7f8 commit da7d2f0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 20 deletions.
10 changes: 6 additions & 4 deletions lib/helpers/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ async function authFor(endpoint, { clientAssertionPayload } = {}) {
case 'client_secret_jwt': {
const timestamp = now();

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

const assertion = await clientAssertion.call(this, endpoint, {
iat: timestamp,
Expand Down
28 changes: 15 additions & 13 deletions test/client/client_instance.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('Client', () => {
describe('#authorizationUrl', function () {
before(function () {
const issuer = new Issuer({
issuer: 'https://rp.example.com',
issuer: 'https://op.example.com',
authorization_endpoint: 'https://op.example.com/auth',
});
this.client = new issuer.Client({
Expand Down Expand Up @@ -1740,8 +1740,8 @@ describe('Client', () => {
describe('when client_secret_jwt', function () {
before(function () {
const issuer = new Issuer({
issuer: 'https://rp.example.com',
token_endpoint: 'https://rp.example.com/token',
issuer: 'https://op.example.com',
token_endpoint: 'https://op.example.com/token',
token_endpoint_auth_signing_alg_values_supported: ['HS256', 'HS384'],
});

Expand Down Expand Up @@ -1774,7 +1774,8 @@ describe('Client', () => {
expect(payload.jti).to.be.a('string');
expect(payload.iat).to.be.a('number');
expect(payload.exp).to.be.a('number');
expect(payload.aud).to.equal('https://rp.example.com/token');
expect(payload.aud).to.include('https://op.example.com/token');
expect(payload.aud).to.include('https://op.example.com');
});

it('can use clientAssertionPayload to change the default payload properties', function () {
Expand All @@ -1800,8 +1801,8 @@ describe('Client', () => {

it('requires client_secret to be set on the client', function () {
const issuer = new Issuer({
issuer: 'https://rp.example.com',
token_endpoint: 'https://rp.example.com/token',
issuer: 'https://op.example.com',
token_endpoint: 'https://op.example.com/token',
});
const client = new issuer.Client({
client_id: 'identifier',
Expand All @@ -1821,8 +1822,8 @@ describe('Client', () => {
describe('works as expected', () => {
before(function () {
const issuer = new Issuer({
issuer: 'https://rp.example.com',
token_endpoint: 'https://rp.example.com/token',
issuer: 'https://op.example.com',
token_endpoint: 'https://op.example.com/token',
token_endpoint_auth_signing_alg_values_supported: ['ES256', 'ES384'],
});

Expand Down Expand Up @@ -1858,7 +1859,8 @@ describe('Client', () => {
expect(payload.jti).to.be.a('string');
expect(payload.iat).to.be.a('number');
expect(payload.exp).to.be.a('number');
expect(payload.aud).to.equal('https://rp.example.com/token');
expect(payload.aud).to.include('https://op.example.com/token');
expect(payload.aud).to.include('https://op.example.com');
});

it('can use clientAssertionPayload to change the default payload properties', function () {
Expand All @@ -1885,8 +1887,8 @@ describe('Client', () => {

it('requires jwks to be provided when the client was instantiated', function () {
const issuer = new Issuer({
issuer: 'https://rp.example.com',
token_endpoint: 'https://rp.example.com/token',
issuer: 'https://op.example.com',
token_endpoint: 'https://op.example.com/token',
});
const client = new issuer.Client({
client_id: 'identifier',
Expand All @@ -1905,8 +1907,8 @@ describe('Client', () => {
describe('alg resolution', () => {
it('rejects when no valid key is present', () => {
const issuer = new Issuer({
issuer: 'https://rp.example.com',
token_endpoint: 'https://rp.example.com/token',
issuer: 'https://op.example.com',
token_endpoint: 'https://op.example.com/token',
});

const keystore = new jose.JWKS.KeyStore();
Expand Down
15 changes: 12 additions & 3 deletions test/client/mtls.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,22 @@ describe('mutual-TLS', () => {

it('uses the mtls endpoint alias for token endpoint when using jwt auth and tls certs', async function () {
let { form: { client_assertion: jwt } } = await clientHelpers.authFor.call(this.jwtAuthClient, 'token');
expect(jose.JWT.decode(jwt).aud).to.eql('https://mtls.op.example.com/token');
let { aud } = jose.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');

({ form: { client_assertion: jwt } } = await clientHelpers.authFor.call(this.jwtAuthClient, 'introspection'));
expect(jose.JWT.decode(jwt).aud).to.eql('https://op.example.com/token/introspect');
({ aud } = jose.JWT.decode(jwt));
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');

({ form: { client_assertion: jwt } } = await clientHelpers.authFor.call(this.jwtAuthClient, 'revocation'));
expect(jose.JWT.decode(jwt).aud).to.eql('https://op.example.com/token/revoke');
({ aud } = jose.JWT.decode(jwt));
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');
});

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

0 comments on commit da7d2f0

Please sign in to comment.