Skip to content

Commit

Permalink
fix: session required client properties control the iss & sid return
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Apr 3, 2019
1 parent 1771655 commit ab08cbe
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 8 deletions.
10 changes: 6 additions & 4 deletions lib/actions/end_session.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,12 @@ module.exports = {
if (client.frontchannelLogoutUri) {
const target = url.parse(client.frontchannelLogoutUri, true);
target.search = null;
Object.assign(target.query, {
sid,
iss: ctx.oidc.issuer,
});
if (client.frontchannelLogoutSessionRequired) {
Object.assign(target.query, {
sid,
iss: ctx.oidc.issuer,
});
}
front.push(url.format(target));
}
}
Expand Down
5 changes: 4 additions & 1 deletion lib/models/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,10 @@ module.exports = function getClient(provider) {
'http://schemas.openid.net/event/backchannel-logout': {},
});
logoutToken.set('jti', nanoid());
logoutToken.set('sid', sid);

if (this.backchannelLogoutSessionRequired) {
logoutToken.set('sid', sid);
}

return logoutToken.sign({ noExp: true })
.then(token => httpRequest.post(this.backchannelLogoutUri, provider.httpOptions({
Expand Down
8 changes: 8 additions & 0 deletions test/backchannel_logout/backchannel_logout.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,13 @@ module.exports = {
redirect_uris: ['https://second-client.example.com/cb'],
backchannel_logout_uri: 'https://second-client.example.com/backchannel_logout',
backchannel_logout_session_required: true,
}, {
client_id: 'no-sid',
client_secret: 'secret',
response_types: ['code id_token'],
grant_types: ['implicit', 'authorization_code', 'refresh_token'],
redirect_uris: ['https://second-client.example.com/cb'],
backchannel_logout_uri: 'https://no-sid.example.com/backchannel_logout',
// backchannel_logout_session_required: false,
}],
};
24 changes: 22 additions & 2 deletions test/backchannel_logout/backchannel_logout.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,35 @@ describe('Back-Channel Logout 1.0', () => {
.filteringRequestBody((body) => {
expect(body).to.match(/^logout_token=(([\w-]+\.?){3})$/);
const decoded = JSON.parse(base64url.decode(RegExp.$1.split('.')[1]));
expect(decoded).to.have.all.keys('sub', 'events', 'iat', 'aud', 'iss', 'jti');
expect(decoded).to.have.all.keys('sub', 'events', 'iat', 'aud', 'iss', 'jti', 'sid');
expect(decoded).to.have.property('events').and.eql({ 'http://schemas.openid.net/event/backchannel-logout': {} });
expect(decoded).to.have.property('aud', 'client');
expect(decoded).to.have.property('sub', 'subject');
expect(decoded).to.have.property('sid', 'foo');
})
.post('/backchannel_logout')
.reply(204);

return client.backchannelLogout('subject', 'foo');
});

it('omits sid when its not required', async function () {
const client = await this.provider.Client.find('no-sid');

nock('https://no-sid.example.com/')
.filteringRequestBody((body) => {
expect(body).to.match(/^logout_token=(([\w-]+\.?){3})$/);
const decoded = JSON.parse(base64url.decode(RegExp.$1.split('.')[1]));
expect(decoded).to.have.all.keys('sub', 'events', 'iat', 'aud', 'iss', 'jti');
expect(decoded).to.have.property('events').and.eql({ 'http://schemas.openid.net/event/backchannel-logout': {} });
expect(decoded).to.have.property('aud', 'no-sid');
expect(decoded).to.have.property('sub', 'subject');
expect(decoded).not.to.have.property('sid');
})
.post('/backchannel_logout')
.reply(204);

return client.backchannelLogout('subject');
return client.backchannelLogout('subject', 'foo');
});
});

Expand Down
8 changes: 8 additions & 0 deletions test/frontchannel_logout/frontchannel_logout.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,13 @@ module.exports = {
redirect_uris: ['https://second-client.example.com/cb'],
frontchannel_logout_uri: 'https://second-client.example.com/frontchannel_logout',
frontchannel_logout_session_required: true,
}, {
client_id: 'no-nothing',
client_secret: 'secret',
response_types: ['code id_token'],
grant_types: ['implicit', 'authorization_code', 'refresh_token'],
redirect_uris: ['https://no-nothing.example.com/cb'],
frontchannel_logout_uri: 'https://no-nothing.example.com/frontchannel_logout',
// frontchannel_logout_session_required: false,
}],
};
11 changes: 10 additions & 1 deletion test/frontchannel_logout/frontchannel_logout.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ describe('Front-Channel Logout 1.0', () => {

const client = await this.provider.Client.find('client');
const client2 = await this.provider.Client.find('second-client');
const client3 = await this.provider.Client.find('no-nothing');

const FRAME = /<iframe src="([^"]+)"><\/iframe>/g;

Expand All @@ -110,7 +111,7 @@ describe('Front-Channel Logout 1.0', () => {
.expect(200)
.expect('content-type', /^text\/html;/)
.expect(({ text: body }) => {
expect(body.match(FRAME)).to.have.length(2);
expect(body.match(FRAME)).to.have.length(3);

(() => {
const { sid } = session.authorizations.client;
Expand All @@ -129,6 +130,14 @@ describe('Front-Channel Logout 1.0', () => {
expect(query).to.have.property('sid', sid);
expect(href.startsWith(`${client2.frontchannelLogoutUri}?`)).to.be.true;
})();

(() => {
const [, match] = FRAME.exec(body);
const { query, href } = parseUrl(match, true);
expect(query).not.to.have.property('iss');
expect(query).not.to.have.property('sid');
expect(href).to.equal(client3.frontchannelLogoutUri);
})();
});
});

Expand Down

0 comments on commit ab08cbe

Please sign in to comment.