Skip to content

Commit 1fee42f

Browse files
author
Eric Lambrecht
committed
add SHA-256 to TokenStrategy
1 parent 0a220e8 commit 1fee42f

File tree

2 files changed

+132
-3
lines changed

2 files changed

+132
-3
lines changed

lib/passport-http-oauth/strategies/token.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,24 @@ TokenStrategy.prototype.authenticate = function(req) {
226226
if (signature !== computedSignature) {
227227
return self.fail(self._challenge('signature_invalid'));
228228
}
229+
230+
} else if (signatureMethod == 'HMAC-SHA256') {
231+
var key = utils.encode(consumerSecret) + '&';
232+
if (tokenSecret) { key += utils.encode(tokenSecret); }
233+
var computedSignature = utils.hmacsha256(key, base);
234+
235+
if (signature !== computedSignature) {
236+
return self.fail(self._challenge('signature_invalid'));
237+
}
238+
229239
} else if (signatureMethod == 'PLAINTEXT') {
230240
var computedSignature = utils.plaintext(consumerSecret, tokenSecret);
231241

232242
if (signature !== computedSignature) {
233243
return self.fail(self._challenge('signature_invalid'));
234244
}
235-
} else{
245+
246+
} else {
236247
return self.fail(self._challenge('signature_method_rejected'), 400);
237248
}
238249

test/strategies/token-test.js

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,72 @@ vows.describe('TokenStrategy').addBatch({
335335
},
336336
},
337337
},
338-
338+
339+
'strategy handling a valid request with credentials in header using HMAC-SHA256 signature': {
340+
topic: function() {
341+
var strategy = new TokenStrategy(
342+
// consumer callback
343+
function(consumerKey, done) {
344+
if (consumerKey == '1234') {
345+
done(null, { id: '1' }, 'keep-this-secret');
346+
} else {
347+
done(new Error('something is wrong'))
348+
}
349+
},
350+
// verify callback
351+
function(accessToken, done) {
352+
if (accessToken == 'abc-123-xyz-789') {
353+
done(null, { username: 'bob' }, 'lips-zipped');
354+
} else {
355+
done(new Error('something is wrong'))
356+
}
357+
}
358+
);
359+
return strategy;
360+
},
361+
362+
'after augmenting with actions': {
363+
topic: function(strategy) {
364+
var self = this;
365+
var req = {};
366+
strategy.success = function(user, info) {
367+
self.callback(null, user, info);
368+
}
369+
strategy.fail = function(challenge, status) {
370+
self.callback(new Error('should not be called'));
371+
}
372+
strategy.error = function(err) {
373+
self.callback(new Error('should not be called'));
374+
}
375+
376+
req.url = '/1/users/show.json?screen_name=jaredhanson&user_id=1705';
377+
req.method = 'GET';
378+
req.headers = {};
379+
req.headers['host'] = '127.0.0.1:3000';
380+
req.headers['authorization'] = 'OAuth oauth_consumer_key="1234",oauth_nonce="A7E738D9A9684A60A40607017735ADAD",oauth_signature_method="HMAC-SHA256",oauth_timestamp="1339004912",oauth_token="abc-123-xyz-789",oauth_version="1.0",oauth_signature="IYG4DLnSdclIVr6rnq49cEjD7AaGqFiUGobOUAjDcpQ="';
381+
req.query = url.parse(req.url, true).query;
382+
req.connection = { encrypted: false };
383+
process.nextTick(function () {
384+
strategy.authenticate(req);
385+
});
386+
},
387+
388+
'should not generate an error' : function(err, user, info) {
389+
assert.isNull(err);
390+
},
391+
'should authenticate' : function(err, user, info) {
392+
assert.equal(user.username, 'bob');
393+
},
394+
'should set scheme to OAuth' : function(err, user, info) {
395+
assert.equal(info.scheme, 'OAuth');
396+
},
397+
'should set consumer' : function(err, user, info) {
398+
assert.equal(info.consumer.id, '1');
399+
assert.strictEqual(info.client, info.consumer);
400+
},
401+
},
402+
},
403+
339404
'strategy handling a valid request with credentials in header with all-caps scheme': {
340405
topic: function() {
341406
var strategy = new TokenStrategy(
@@ -797,7 +862,60 @@ vows.describe('TokenStrategy').addBatch({
797862
},
798863
},
799864
},
800-
865+
866+
'strategy handling a request with invalid HMAC-SHA256 signature': {
867+
topic: function() {
868+
var strategy = new TokenStrategy(
869+
// consumer callback
870+
function(consumerKey, done) {
871+
done(null, { id: '1' }, 'keep-this-secret');
872+
},
873+
// verify callback
874+
function(accessToken, done) {
875+
done(null, { username: 'bob' }, 'lips-not-zipped');
876+
}
877+
);
878+
return strategy;
879+
},
880+
881+
'after augmenting with actions': {
882+
topic: function(strategy) {
883+
var self = this;
884+
var req = {};
885+
strategy.success = function(user, info) {
886+
self.callback(new Error('should not be called'));
887+
}
888+
strategy.fail = function(challenge, status) {
889+
self.callback(null, challenge, status);
890+
}
891+
strategy.error = function(err) {
892+
self.callback(new Error('should not be called'));
893+
}
894+
895+
req.url = '/1/users/show.json?screen_name=jaredhanson&user_id=1705';
896+
req.method = 'GET';
897+
req.headers = {};
898+
req.headers['host'] = '127.0.0.1:3000';
899+
req.headers['authorization'] = 'OAuth oauth_consumer_key="1234",oauth_nonce="A7E738D9A9684A60A40607017735ADAD",oauth_signature_method="HMAC-SHA256",oauth_timestamp="1339004912",oauth_token="abc-123-xyz-789",oauth_version="1.0",oauth_signature="TBrJJJWS896yWrbklSbhEd9MGQc%3D"';
900+
req.query = url.parse(req.url, true).query;
901+
req.connection = { encrypted: false };
902+
process.nextTick(function () {
903+
strategy.authenticate(req);
904+
});
905+
},
906+
907+
'should not generate an error' : function(err, challenge, status) {
908+
assert.isNull(err);
909+
},
910+
'should respond with challenge' : function(err, challenge, status) {
911+
assert.equal(challenge, 'OAuth realm="Users", oauth_problem="signature_invalid"');
912+
},
913+
'should respond with default status' : function(err, challenge, status) {
914+
assert.isUndefined(status);
915+
},
916+
},
917+
},
918+
801919
'strategy handling a request with unknown signature method': {
802920
topic: function() {
803921
var strategy = new TokenStrategy(

0 commit comments

Comments
 (0)