Skip to content

Instantly share code, notes, and snippets.

@dmansfield
Created August 7, 2015 13:27
Show Gist options
  • Save dmansfield/c75817dcacc2393da0a7 to your computer and use it in GitHub Desktop.
Save dmansfield/c75817dcacc2393da0a7 to your computer and use it in GitHub Desktop.
Node.js HTTP client with kerberos/gssapi/negotiate/spnego authentication
//
// tested with kerberos 0.0.12 on linux against apache running mod_auth_kerb with Samba AD providing KDC
//
var Kerberos = require('kerberos').Kerberos;
var kerberos = new Kerberos();
var http = require('http');
function httpget(opts, callback) {
console.log('submitting to '+(opts.hostname||opts.host)+' with authorization header: '+(opts.headers||{}).authorization);
var req = http.get(opts, function(res) {
if (res.statusCode == 401) {
submitWithAuthorization(req, opts, callback);
return;
}
callback(res);
});
return req;
}
function submitWithAuthorization(oldreq, opts, callback) {
kerberos.authGSSClientInit("HTTP@"+(opts.hostname || opts.host), 0, function(err, ctx) {
if (err) {
throw new Error(""+err);
}
console.log('done init '+ctx);
kerberos.authGSSClientStep(ctx, "", function (err) {
if (err) {
throw new Error(""+err);
}
console.log('done step '+ctx.response);
var headers = opts.headers || {};
headers.authorization = "Negotiate "+ctx.response;
opts.headers = headers;
var newreq = httpget(opts, callback);
// tell oldReq "owner" about newReq. resubmit is an "unofficial" event
oldreq.emit('resubmit', newreq);
kerberos.authGSSClientClean(ctx, function(err) {
if (err) {
throw new Error(""+err);
}
});
});
});
}
// //////////////////////////////////////////////////////////////////
var options = {
hostname : "somehost.protected.by.spnego.example.com"
, path : "/"
};
var req = httpget(options, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
console.log("BODY: "+body);
});
});
req.on('resubmit', function(newreq) {
console.log('request resubmitted');
req = newreq;
});
return;
@91pavan
Copy link

91pavan commented Jan 19, 2016

Hi @dmansfield, thanks for the gist. Very useful..

When I execute this, I get the following error :

done init [object KerberosContext]
{ [Error: authenticate_gss_client_step(gss_init_sec_context): Unspecified GSS failure.  
Minor code may provide more information: No Kerberos credentials available] code: -1 }

Any idea how I can fix this?

Should there be a keytab file for the user against which i'm authenticating? If so, where should I place it?

@SgtPooki
Copy link

@91pavan try running kinit -f in your terminal prior to running this script.

@coreylarew
Copy link

I keep getting undefined for the security header output. Any suggestions?

@cnayan
Copy link

cnayan commented Aug 30, 2019

What can be done to make it work on Windows?

@savely-krasovsky
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment