Skip to content

Commit

Permalink
validating tokens according to response_type and access_tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
luisrudge committed Mar 21, 2018
1 parent 7f83808 commit 45b35d0
Show file tree
Hide file tree
Showing 8 changed files with 343 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Parameters:
### API

- **authorize(options)**: Redirects to the `/authorize` endpoint to start an authentication/authorization transaction.
Auth0 will call back to your application with the results at the specified `redirectUri`.
Auth0 will call back to your application with the results at the specified `redirectUri`. **The default scope for this method is `openid profile email`**

```js
auth0.authorize({
Expand Down
2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ <h2>Console:</h2>
domain: 'brucke.auth0.com',
redirectUri: 'https://localhost:3000/example/',
clientID: 'k5u3o2fiAA8XweXEEX604KCwCjzjtMU6',
responseType: 'token',
responseType: 'token id_token',
plugins: [
new CordovaAuth0Plugin()
]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"license": "MIT",
"dependencies": {
"base64-js": "^1.2.0",
"idtoken-verifier": "^1.1.2",
"idtoken-verifier": "^1.2.0",
"qs": "^6.4.0",
"superagent": "^3.8.2",
"url-join": "^1.1.0",
Expand Down
4 changes: 2 additions & 2 deletions src/helper/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ function buildResponse(error, description) {
};
}

function invalidJwt(description) {
function invalidToken(description) {
return buildResponse('invalid_token', description);
}

module.exports = {
buildResponse: buildResponse,
invalidJwt: invalidJwt
invalidToken: invalidToken
};
49 changes: 46 additions & 3 deletions src/web-auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ function WebAuth(options) {
* @param {String} options.hash the url hash. If not provided it will extract from window.location.hash
* @param {String} [options.state] value originally sent in `state` parameter to {@link authorize} to mitigate XSRF
* @param {String} [options.nonce] value originally sent in `nonce` parameter to {@link authorize} to prevent replay attacks
* @param {String} [options.responseType] type of the response used by OAuth 2.0 flow. It can be any space separated list of the values `token`, `id_token`. For this specific method, we'll only use this value to check if the hash contains the tokens requested in the responseType.
* @param {authorizeCallback} cb
*/
WebAuth.prototype.parseHash = function(options, cb) {
Expand Down Expand Up @@ -160,6 +161,31 @@ WebAuth.prototype.parseHash = function(options, cb) {
) {
return cb(null, null);
}
var responseTypes = (this.baseOptions.responseType || options.responseType || '').split(' ');
if (
responseTypes.length > 0 &&
responseTypes.indexOf('token') !== -1 &&
!parsedQs.hasOwnProperty('access_token')
) {
return cb(
error.buildResponse(
'invalid_hash',
'response_type contains `token`, but the parsed hash does not contain an `access_token` property'
)
);
}
if (
responseTypes.length > 0 &&
responseTypes.indexOf('id_token') !== -1 &&
!parsedQs.hasOwnProperty('id_token')
) {
return cb(
error.buildResponse(
'invalid_hash',
'response_type contains `id_token`, but the parsed hash does not contain an `id_token` property'
)
);
}
return this.validateAuthenticationResponse(options, parsedQs, cb);
};

Expand All @@ -179,12 +205,14 @@ WebAuth.prototype.parseHash = function(options, cb) {
*/
WebAuth.prototype.validateAuthenticationResponse = function(options, parsedHash, cb) {
var _this = this;
options.__enableIdPInitiatedLogin =
options.__enableIdPInitiatedLogin || options.__enableImpersonation;
var state = parsedHash.state;
var transaction = this.transactionManager.getStoredTransaction(state);
var transactionState = options.state || (transaction && transaction.state) || null;

var transactionStateMatchesState = transactionState === state;
var shouldBypassStateChecking = !state && !transactionState && options.__enableImpersonation;
var shouldBypassStateChecking = !state && !transactionState && options.__enableIdPInitiatedLogin;

if (!shouldBypassStateChecking && !transactionStateMatchesState) {
return cb({
Expand Down Expand Up @@ -218,7 +246,22 @@ WebAuth.prototype.validateAuthenticationResponse = function(options, parsedHash,
payload
) {
if (!validationError) {
return callback(null, payload);
if (!parsedHash.access_token) {
return callback(null, payload);
}
// here we're absolutely sure that the id_token's alg is RS256
// and that the id_token is valid, so we can check the access_token
return new IdTokenVerifier().validateAccessToken(
parsedHash.access_token,
'RS256',
payload.at_hash,
function(err) {
if (err) {
return callback(error.invalidToken(err.message));
}
return callback(null, payload);
}
);
}
if (validationError.error !== 'invalid_token') {
return callback(validationError);
Expand Down Expand Up @@ -279,7 +322,7 @@ WebAuth.prototype.validateToken = function(token, nonce, cb) {

verifier.verify(token, nonce, function(err, payload) {
if (err) {
return cb(error.invalidJwt(err.message));
return cb(error.invalidToken(err.message));
}

cb(null, payload);
Expand Down
5 changes: 5 additions & 0 deletions test/plugins/cordova.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var IdTokenVerifier = require('idtoken-verifier');
var expect = require('expect.js');
var stub = require('sinon').stub;

Expand Down Expand Up @@ -100,6 +101,9 @@ describe('auth0.plugins.cordova', function() {

context('PopupHandler', function() {
beforeEach(function() {
stub(IdTokenVerifier.prototype, 'validateAccessToken', function(at, alg, atHash, cb) {
cb(null);
});
var _this = this;
this.events = {};
var webAuth = new WebAuth({
Expand Down Expand Up @@ -132,6 +136,7 @@ describe('auth0.plugins.cordova', function() {
});

afterEach(function() {
IdTokenVerifier.prototype.validateAccessToken.restore();
delete global.window;
this.events = null;
this.popupHandler = null;
Expand Down
Loading

0 comments on commit 45b35d0

Please sign in to comment.