Skip to content

Instantly share code, notes, and snippets.

@hillar
Created October 17, 2013 19:33
Show Gist options
  • Save hillar/7030859 to your computer and use it in GitHub Desktop.
Save hillar/7030859 to your computer and use it in GitHub Desktop.
passport strategy for client certificate need a lot of work...
passport.use(new SSLClientCertificateStrategy({ca: Config.get('clientCertificateCA'),
crl: Config.get('clientCertificateCRL', []),
ocsp: Config.get('clientCertificateOCSP',[])},
function(userid, done) {
Db.get("users", "user", userid, function(err, suser) {
if (err) {return done(err);}
if (!suser || !suser.exists) {console.log(userid, "doesn't exist"); return done(null, false);}
if (!suser._source.enabled) {console.log(userid, "not enabled"); return done("Not enabled");}
suser._source.settings = suser._source.settings || {};
if (suser._source.emailSearch === undefined) {suser._source.emailSearch = false;}
if (suser._source.removeEnabled === undefined) {suser._source.removeEnabled = false;}
if (Config.get("multiES", false)) {suser._source.createEnabled = false;}
return done(null, suser._source, {ha1: Config.store2ha1(suser._source.passStore)});
});
},
function (options, done) {
//TODO: Should check nonce here
return done(null, true);
}
));
// -----------------------------------------------
/**
* Module dependencies.
*/
var passport = require('passport')
, util = require('util')
, BadRequestError = require('./errors/badrequesterror');
/**
* `Strategy` constructor. (skeleton from https://github.com/yuri-karadzhov/passport-hash/blob/master/lib/passport-hash/strategy.js)
*
* The client certificate authentication strategy authenticates requests based on the
* TLS getPeerCertificate
*
* Applications must supply a `verify` callback which accepts `....`, and then
* calls the `done` callback supplying a
* `user`, which should be set to `false` if the cert is not valid.
* If an exception occured, `err` should be set.
*
*
* Options:
* - `ca`
* - `crl`
* - `ocsp`
*
* Examples:
*
* passport.use(new SSLClientCertificateStrategy({ca:['ca.crt'],crl:['revoked.crl'],['http://ocsp.some.cc']},
* function(userid, done) {
* do someting.., function (err, user) {
* done(err, user);
* });
* }
* ));
*
* @param {Object} options
* @param {Function} verify
* @api public
*/
function Strategy(options, verify) {
if (!options || !options.ca) throw new Error('strategy requires at least certificate authority certificate fail');
if (!verify) throw new Error('strategy requires a verify function');
this._ca = options.ca
this._crl = options.crl || [];
this._ocsp = options.ocsp || [];
passport.Strategy.call(this);
this.name = 'clientcertificate';
this._verify = verify;
this._passReqToCallback = options.passReqToCallback;
}
/**
* Inherit from `passport.Strategy`.
*/
util.inherits(Strategy, passport.Strategy);
/**
* Authenticate request based on the client certificate.
*
* @param {Object} req
* @api protected
*/
Strategy.prototype.authenticate = function(req) {
var clientCertificate = req.connection.getPeerCertificate();
if (!clientCertificate) {
return this.fail(new BadRequestError('Missing client cert'));
}
if (!req.client.authorized) {
return this.fail('reason:' + req.client.authorizationError)
}
if (!clientCertificate.subject.serialNumber){
return this.fail('reason:' + 'no user id')
}
var self = this;
function verified(err, user, info) {
if (err) { return self.error(err); }
if (!user) { return self.fail(info); }
self.success(user, info);
}
if (self._passReqToCallback) {
this._verify(req, clientCertificate.subject.serialNumber, verified);
} else {
this._verify(clientCertificate.subject.serialNumber, verified);
}
}
/**
* Expose `Strategy`.
*/
module.exports = Strategy;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment