function BasicStrategy(options, verify) {
if (typeof options == 'function') {
verify = options;
options = {};
}
if (!verify) throw new Error('HTTP Basic authentication strategy requires a verify function');
passport.Strategy.call(this);
this.name = 'basic';
this._verify = verify;
this._realm = options.realm || 'Users';
this._passReqToCallback = options.passReqToCallback;
}n/a
function Strategy() {
}n/a
function DigestStrategy(options, secret, validate) {
if (typeof options == 'function') {
validate = secret;
secret = options;
options = {};
}
if (!secret) throw new Error('HTTP Digest authentication strategy requires a secret function');
passport.Strategy.call(this);
this.name = 'digest';
this._secret = secret;
this._validate = validate;
this._realm = options.realm || 'Users';
if (options.domain) {
this._domain = (Array.isArray(options.domain)) ? options.domain : [ options.domain ];
}
this._opaque = options.opaque;
this._algorithm = options.algorithm;
if (options.qop) {
this._qop = (Array.isArray(options.qop)) ? options.qop : [ options.qop ];
}
}n/a
function BasicStrategy(options, verify) {
if (typeof options == 'function') {
verify = options;
options = {};
}
if (!verify) throw new Error('HTTP Basic authentication strategy requires a verify function');
passport.Strategy.call(this);
this.name = 'basic';
this._verify = verify;
this._realm = options.realm || 'Users';
this._passReqToCallback = options.passReqToCallback;
}n/a
function Strategy() {
}n/a
_challenge = function () {
return 'Basic realm="' + this._realm + '"';
}n/a
authenticate = function (req) {
var authorization = req.headers['authorization'];
if (!authorization) { return this.fail(this._challenge()); }
var parts = authorization.split(' ')
if (parts.length < 2) { return this.fail(400); }
var scheme = parts[0]
, credentials = new Buffer(parts[1], 'base64').toString().split(':');
if (!/Basic/i.test(scheme)) { return this.fail(this._challenge()); }
if (credentials.length < 2) { return this.fail(400); }
var userid = credentials[0];
var password = credentials[1];
if (!userid || !password) {
return this.fail(this._challenge());
}
var self = this;
function verified(err, user) {
if (err) { return self.error(err); }
if (!user) { return self.fail(self._challenge()); }
self.success(user);
}
if (self._passReqToCallback) {
this._verify(req, userid, password, verified);
} else {
this._verify(userid, password, verified);
}
}...
return done(null, user);
});
}
));
#### Authenticate Requests
Use `passport.authenticate()`, specifying the `'basic'` strategy, to
authenticate requests. Requests containing an 'Authorization' header do not
require session support, so the `session` option can be set to `false`.
For example, as route middleware in an [Express](http://expressjs.com/)
application:
app.get('/private',
...function Strategy() {
}n/a
function Strategy() {
}n/a
authenticate = function (req, options) {
throw new Error('Strategy#authenticate must be overridden by subclass');
}...
return done(null, user);
});
}
));
#### Authenticate Requests
Use `passport.authenticate()`, specifying the `'basic'` strategy, to
authenticate requests. Requests containing an 'Authorization' header do not
require session support, so the `session` option can be set to `false`.
For example, as route middleware in an [Express](http://expressjs.com/)
application:
app.get('/private',
...function DigestStrategy(options, secret, validate) {
if (typeof options == 'function') {
validate = secret;
secret = options;
options = {};
}
if (!secret) throw new Error('HTTP Digest authentication strategy requires a secret function');
passport.Strategy.call(this);
this.name = 'digest';
this._secret = secret;
this._validate = validate;
this._realm = options.realm || 'Users';
if (options.domain) {
this._domain = (Array.isArray(options.domain)) ? options.domain : [ options.domain ];
}
this._opaque = options.opaque;
this._algorithm = options.algorithm;
if (options.qop) {
this._qop = (Array.isArray(options.qop)) ? options.qop : [ options.qop ];
}
}n/a
function Strategy() {
}n/a
_challenge = function () {
// TODO: For maximum flexibility, a mechanism for delegating the generation
// of the nonce and opaque data to the application would be useful.
var challenge = 'Digest realm="' + this._realm + '"';
if (this._domain) {
challenge += ', domain="' + this._domain.join(' ') + '"';
}
challenge += ', nonce="' + nonce(32) + '"';
if (this._opaque) {
challenge += ', opaque="' + this._opaque + '"';
}
if (this._algorithm) {
challenge += ', algorithm=' + this._algorithm;
}
if (this._qop) {
challenge += ', qop="' + this._qop.join(',') + '"';
}
return challenge;
}n/a
authenticate = function (req) {
var authorization = req.headers['authorization'];
if (!authorization) { return this.fail(this._challenge()); }
var parts = authorization.split(' ')
if (parts.length < 2) { return this.fail(400); }
var scheme = parts[0]
, params = parts.slice(1).join(' ');
if (!/Digest/i.test(scheme)) { return this.fail(this._challenge()); }
var creds = parse(params);
if (Object.keys(creds).length === 0) { return this.fail(400); }
if (!creds.username) {
return this.fail(this._challenge());
}
if (req.url !== creds.uri) {
return this.fail(400);
}
var self = this;
// Use of digest authentication requires a password (aka shared secret) known
// to both the client and server, but not transported over the wire. This
// secret is needed in order to compute the hashes required to authenticate
// the request, and can be obtained by calling the secret() function the
// application provides to the strategy. Because username is the key for a
// database query, a `user` instance is also obtained from this callback.
// However, the user will only be successfully authenticated if the password
// is correct, as indicated by the challenge response matching the computed
// value.
this._secret(creds.username, function(err, user, password) {
if (err) { return self.error(err); }
if (!user) { return self.fail(self._challenge()); }
var ha1;
if (!creds.algorithm || creds.algorithm === 'MD5') {
if (typeof password === 'object' && password.ha1) {
ha1 = password.ha1;
} else {
ha1 = md5(creds.username + ":" + creds.realm + ":" + password);
}
} else if (creds.algorithm === 'MD5-sess') {
// TODO: The nonce and cnonce used here should be the initial nonce
// value generated by the server and the first nonce value used by
// the client. This creates a 'session key' for the authentication
// of subsequent requests. The storage of the nonce values and the
// resulting session key needs to be investigated.
//
// See RFC 2617 (Section 3.2.2.2) for further details.
ha1 = md5(md5(creds.username + ":" + creds.realm + ":" + password) + ":" + creds.nonce + ":" + creds.cnonce);
} else {
return self.fail(400);
}
var ha2;
if (!creds.qop || creds.qop === 'auth') {
ha2 = md5(req.method + ":" + creds.uri);
} else if (creds.qop === 'auth-int') {
// TODO: Implement support for auth-int. Note that the raw entity body
// will be needed, not the parsed req.body property set by Connect's
// bodyParser middleware.
//
// See RFC 2617 (Section 3.2.2.3 and Section 3.2.2.4) for further
// details.
return self.error(new Error('auth-int not implemented'));
} else {
return self.fail(400);
}
var digest;
if (!creds.qop) {
digest = md5(ha1 + ":" + creds.nonce + ":" + ha2);
} else if (creds.qop === 'auth' || creds.qop === 'auth-int') {
digest = md5(ha1 + ":" + creds.nonce + ":" + creds.nc + ":" + creds.cnonce + ":" + creds.qop + ":" + ha2);
} else {
return self.fail(400);
}
if (creds.response != digest) {
return self.fail(self._challenge());
} else {
if (self._validate) {
self._validate({
nonce: creds.nonce,
cnonce: creds.cnonce,
nc: creds.nc,
opaque: creds.opaque
},
function(err, valid) {
if (err) { return self.error(err); }
if (!valid) { return self.fail(self._challenge()); }
self.success(user);
});
} else {
self.success(user);
}
}
});
}...
return done(null, user);
});
}
));
#### Authenticate Requests
Use `passport.authenticate()`, specifying the `'basic'` strategy, to
authenticate requests. Requests containing an 'Authorization' header do not
require session support, so the `session` option can be set to `false`.
For example, as route middleware in an [Express](http://expressjs.com/)
application:
app.get('/private',
...