This repository has been archived by the owner on Feb 25, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
feat(RPInitiatedLogoutRequest): First draft of RP Initiated Logout Request handling #15
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
'use strict' | ||
|
||
/** | ||
* Dependencies | ||
* @ignore | ||
*/ | ||
const qs = require('qs') | ||
const BaseRequest = require('./BaseRequest') | ||
|
||
class RPInitiatedLogoutRequest extends BaseRequest { | ||
/** | ||
* RP Initiated Logout Request Handler | ||
* | ||
* @see https://openid.net/specs/openid-connect-session-1_0.html#RPLogout | ||
* @see https://openid.net/specs/openid-connect-frontchannel-1_0.html#RPInitiated | ||
* @see https://openid.net/specs/openid-connect-backchannel-1_0.html#RPInitiated | ||
* | ||
* @param req {HTTPRequest} | ||
* @param res {HTTPResponse} | ||
* @param provider {Provider} | ||
* @returns {Promise} | ||
*/ | ||
static handle (req, res, provider) { | ||
let { host } = provider | ||
let request = new RPInitiatedLogoutRequest(req, res, provider) | ||
|
||
Promise | ||
.resolve(request) | ||
.then(request.validate) | ||
|
||
// From: https://openid.net/specs/openid-connect-session-1_0.html#RPLogout | ||
// At the logout endpoint, the OP SHOULD ask the End-User whether they want | ||
// to log out of the OP as well. If the End-User says "yes", then the OP | ||
// MUST log out the End-User. | ||
.then(host.logout) | ||
|
||
.then(request.redirectOrRespond) | ||
.catch(request.internalServerError) | ||
} | ||
|
||
/** | ||
* Constructor | ||
* | ||
* Session spec defines the following params to the RP Initiated Logout request: | ||
* - `id_token_hint` | ||
* - `post_logout_redirect_uri` | ||
* - `state` | ||
* | ||
* @param req {HTTPRequest} | ||
* @param res {HTTPResponse} | ||
* @param provider {Provider} | ||
*/ | ||
constructor (req, res, provider) { | ||
super(req, res, provider) | ||
this.params = RPInitiatedLogoutRequest.getParams(this) | ||
} | ||
|
||
/** | ||
* Validate | ||
* | ||
* @see https://openid.net/specs/openid-connect-session-1_0.html#RPLogout | ||
* | ||
* @param request {RPInitiatedLogoutRequest} | ||
*/ | ||
validate (request) { | ||
/** | ||
* `state` parameter - no validation need it. Will be passed back to the RP | ||
* in the `redirectToRP()` step. | ||
*/ | ||
|
||
/** | ||
* TODO: Validate `id_token_hint` (validate as ID Token *except* for `aud`) | ||
* | ||
* RECOMMENDED. Previously issued ID Token passed to the logout endpoint as | ||
* a hint about the End-User's current authenticated session with the Client. | ||
* This is used as an indication of the identity of the End-User that the RP | ||
* is requesting be logged out by the OP. The OP *need not* be listed as an | ||
* audience of the ID Token when it is used as an `id_token_hint` value. | ||
*/ | ||
|
||
/** | ||
* TODO: Validate that `post_logout_redirect_uri` has been registered | ||
* | ||
* The value MUST have been previously registered with the OP, either using | ||
* the `post_logout_redirect_uris` Registration parameter | ||
* or via another mechanism. | ||
* | ||
* Question: what's this about 'another mechanism'? | ||
*/ | ||
} | ||
|
||
/** | ||
* Redirect to RP or Respond | ||
* | ||
* In some cases, the RP will request that the End-User's User Agent to be | ||
* redirected back to the RP after a logout has been performed. Post-logout | ||
* redirection is only done when the logout is RP-initiated, in which case the | ||
* redirection target is the `post_logout_redirect_uri` query parameter value | ||
* used by the initiating RP; otherwise it is not done. | ||
* | ||
* @see https://openid.net/specs/openid-connect-session-1_0.html#RedirectionAfterLogout | ||
* | ||
* @returns {null} | ||
*/ | ||
redirectOrRespond () { | ||
let { params: { post_logout_redirect_uri: postLogoutRedirectUri } } = this | ||
|
||
if (postLogoutRedirectUri) { | ||
this.redirectToRP() | ||
} else { | ||
this.respond() | ||
} | ||
} | ||
|
||
/** | ||
* Redirect To RP | ||
* | ||
* Redirects the user-agent back to the RP, if requested (by the RP providing | ||
* a `post_logout_redirect_uri` parameter). Also passes through the `state` | ||
* parameter, if supplied by the RP. | ||
* | ||
* @returns {null} | ||
*/ | ||
redirectToRP () { | ||
let { res, params: { post_logout_redirect_uri: uri, state } } = this | ||
|
||
if (state) { | ||
let response = qs.stringify({ state }) | ||
uri = `${uri}?${response}` | ||
} | ||
|
||
res.redirect(uri) // 302 redirect | ||
} | ||
|
||
/** | ||
* Respond | ||
* | ||
* Responds to the RP Initiated Logout request with a 204 No Content, if the | ||
* RP did not supply a `post_logout_redirect_uri` parameter. | ||
* | ||
* @returns {null} | ||
*/ | ||
respond () { | ||
let { res } = this | ||
|
||
res.set({ | ||
'Cache-Control': 'no-store', | ||
'Pragma': 'no-cache' | ||
}) | ||
|
||
res.status(204).send() | ||
} | ||
} | ||
|
||
module.exports = RPInitiatedLogoutRequest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
'use strict' | ||
|
||
// const chai = require('chai') | ||
// const expect = chai.expect | ||
|
||
const RPInitiatedLogoutRequest = require('../../src/handlers/RPInitiatedLogoutRequest') | ||
|
||
describe('RPInitiatedLogoutRequest', () => { | ||
describe('handle()', () => { | ||
it('should validate the request') | ||
it('should invoke injected host.logout') | ||
it('should invoke redirectOrRespond() if validated') | ||
}) | ||
|
||
describe('constructor()', () => { | ||
it('should parse the incoming request params') | ||
}) | ||
|
||
describe('redirectOrRespond()', () => { | ||
it('should redirect to RP if logout uri provided') | ||
it('should respond with a 204 if no logout uri provided') | ||
}) | ||
|
||
describe('redirectToRP()', () => { | ||
it('should redirect to provided URI') | ||
it('should pass through the state param') | ||
}) | ||
}) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Binds just fine the way it is.