diff --git a/lib/passport-openid/strategy.js b/lib/passport-openid/strategy.js index 44ec7ee..2df4704 100644 --- a/lib/passport-openid/strategy.js +++ b/lib/passport-openid/strategy.js @@ -23,8 +23,8 @@ var passport = require('passport') * * Applications must supply a `verify` callback which accepts an `identifier`, * an optional service-specific `profile`, an optional set of policy extensions - * and then calls the `done` callback supplying a `user`, which should be set to - * `false` if the credentials are not valid. If an exception occured, `err` + * and then calls the `done` callback supplying a `user`, which should be set to + * `false` if the credentials are not valid. If an exception occured, `err` * should be set. * * Options: @@ -34,7 +34,7 @@ var passport = require('passport') * - `pape` when present, enables the OpenID Provider Authentication Policy Extension * (http://openid.net/specs/openid-provider-authentication-policy-extension-1_0.html) * - `pape.maxAuthAge` sets the PAPE maximum authentication age in seconds - * - `pape.preferredAuthPolicies` sets the preferred set of PAPE authentication policies for the + * - `pape.preferredAuthPolicies` sets the preferred set of PAPE authentication policies for the * relying party to use for example `multi-factor`, `multi-factor-physical` * or `phishing-resistant` (either an array or a string) * - `identifierField` field name where the OpenID identifier is found, defaults to 'openid_identifier' @@ -57,7 +57,7 @@ var passport = require('passport') * returnURL: 'http://localhost:3000/auth/openid/return', * realm: 'http://localhost:3000/', * profile: true, - * pape: { maxAuthAge : 600 } + * pape: { maxAuthAge : 600 } * }, * function(identifier, profile, done) { * User.findByOpenID(identifier, function (err, user) { @@ -73,24 +73,24 @@ var passport = require('passport') function Strategy(options, verify) { if (!options.returnURL) throw new Error('OpenID authentication requires a returnURL option'); if (!verify) throw new Error('OpenID authentication strategy requires a verify callback'); - + passport.Strategy.call(this); this.name = 'openid'; this._verify = verify; this._profile = options.profile; this._pape = options.pape; this._passReqToCallback = options.passReqToCallback; - + var extensions = []; if (options.profile) { var sreg = new openid.SimpleRegistration({ "fullname" : true, - "nickname" : true, - "email" : true, - "dob" : true, - "gender" : true, + "nickname" : true, + "email" : true, + "dob" : true, + "gender" : true, "postcode" : true, - "country" : true, + "country" : true, "timezone" : true, "language" : true }); @@ -127,23 +127,23 @@ function Strategy(options, verify) { var pape = new openid.PAPE(papeOptions); extensions.push(pape); } - + if (options.oauth) { var oauthOptions = {}; oauthOptions.consumerKey = options.oauth.consumerKey; oauthOptions.scope = options.oauth.scope; - + var oauth = new openid.OAuthHybrid(oauthOptions); extensions.push(oauth); } - + this._relyingParty = new openid.RelyingParty( options.returnURL, options.realm, (options.stateless === undefined) ? false : options.stateless, (options.secure === undefined) ? true : options.secure, extensions); - + this._providerURL = options.providerURL; this._identifierField = options.identifierField || 'openid_identifier'; } @@ -163,27 +163,35 @@ util.inherits(Strategy, passport.Strategy); */ Strategy.prototype.authenticate = function(req) { - if (req.query && req.query['openid.mode']) { + // Added support for post : req.bod + if (req.query && (req.query['openid.mode'] || req.body['openid.mode'])) { // The request being authenticated contains an `openid.mode` parameter in // the query portion of the URL. This indicates that the OpenID Provider // is responding to a prior authentication request with either a positive or // negative assertion. If a positive assertion is received, it will be // verified according to the rules outlined in the OpenID 2.0 specification. - + // NOTE: node-openid (0.3.1), which is used internally, will treat a cancel // response as an error, setting `err` in the verifyAssertion // callback. However, for consistency with Passport semantics, a // cancel response should be treated as an authentication failure, // rather than an exceptional error. As such, this condition is // trapped and handled prior to being given to node-openid. - - if (req.query['openid.mode'] === 'cancel') { return this.fail({ message: 'OpenID authentication canceled' }); } - + + if (req.query['openid.mode'] === 'cancel' || req.body['openid.mode'] === 'cancel') { return this.fail({ message: 'OpenID authentication canceled' }); } + var self = this; - this._relyingParty.verifyAssertion(req.url, function(err, result) { + var assertUrl; + if(req.query['openid.mode']) { + assertUrl = req.url; + }else{ + assertUrl = req.url+"?"+qs.stringify(req.body); + } + + this._relyingParty.verifyAssertion(assertUrl, function(err, result) { if (err) { return self.error(new InternalOpenIDError('Failed to verify assertion', err)); } if (!result.authenticated) { return self.error(new Error('OpenID authentication failed')); } - + var profile = self._parseProfileExt(result); var pape = self._parsePAPEExt(result); var oauth = self._parseOAuthExt(result); @@ -193,8 +201,8 @@ Strategy.prototype.authenticate = function(req) { if (!user) { return self.fail(info); } self.success(user, info); } - - + + var arity = self._verify.length; if (self._passReqToCallback) { if (arity == 6) { @@ -232,7 +240,7 @@ Strategy.prototype.authenticate = function(req) { // OpenID provider. Optionally, and by default, an association will be // established with the OpenID provider which is used to verify subsequent // protocol messages and reduce round trips. - + var identifier = undefined; if (req.body && req.body[this._identifierField]) { identifier = req.body[this._identifierField]; @@ -241,7 +249,7 @@ Strategy.prototype.authenticate = function(req) { } else if (this._providerURL) { identifier = this._providerURL; } - + if (!identifier) { return this.fail(new BadRequestError('Missing OpenID identifier')); } var self = this; @@ -252,7 +260,7 @@ Strategy.prototype.authenticate = function(req) { } } -/** +/** * Register a function used to save associations. * * An association establishes a shared secret between a relying party and an @@ -298,7 +306,7 @@ Strategy.prototype.saveAssociation = function(fn) { return this; // return this for chaining } -/** +/** * Register a function used to load associations. * * An association establishes a shared secret between a relying party and an @@ -353,7 +361,7 @@ Strategy.prototype.loadAssociation = function(fn) { return this; // return this for chaining } -/** +/** * Register a function used to cache discovered info. * * Caching discovered information about a provider can significantly speed up @@ -384,13 +392,13 @@ Strategy.prototype.loadAssociation = function(fn) { * @return {Strategy} for chaining * @api public */ -Strategy.prototype.saveDiscoveredInfo = +Strategy.prototype.saveDiscoveredInfo = Strategy.prototype.saveDiscoveredInformation = function(fn) { openid.saveDiscoveredInformation = fn; return this; // return this for chaining } -/** +/** * Register a function used to load discovered info from cache. * * Caching discovered information about a provider can significantly speed up @@ -439,11 +447,11 @@ Strategy.prototype.loadDiscoveredInformation = function(fn) { */ Strategy.prototype._parseProfileExt = function(params) { var profile = {}; - + // parse simple registration parameters profile.displayName = params['fullname']; profile.emails = [{ value: params['email'] }]; - + // parse attribute exchange parameters profile.name = { familyName: params['lastname'], givenName: params['firstname'] }; @@ -483,5 +491,5 @@ Strategy.prototype._parseOAuthExt = function(params) { /** * Expose `Strategy`. - */ + */ module.exports = Strategy; diff --git a/package.json b/package.json index dfb6f13..2e48f60 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,14 @@ }, "licenses": [ { "type": "MIT", - "url": "http://www.opensource.org/licenses/MIT" + "url": "http://www.opensource.org/licenses/MIT" } ], "main": "./lib/passport-openid", "dependencies": { "pkginfo": "0.2.x", "passport": "~0.1.3", - "openid": "0.5.x" + "openid": "0.5.x", + "qs": "^2.2.4" }, "devDependencies": { "vows": "0.6.x"