Thanks to grawity, I was able to solve this.
The problem was caused by incorrect principal formatting and the wrong encryption type when generating the http.keytab
.
New-ADUser -Name "schoolieService" -SamAccountName "schoolieService" `
-AccountPassword (ConvertTo-SecureString 'SH8DXIrR2iWY' -AsPlainText -Force) `
-Enabled $true
setspn -S HTTP/schoolie-server.schooliead.local schoolieService
ktpass /princ HTTP/[email protected] `
/mapuser [email protected] `
/pass SH8DXIrR2iWY `
/out ./http.keytab `
/ptype KRB5_NT_PRINCIPAL `
/crypto RC4-HMAC-NT
Note: the
service
string uses a slightly different encoding than the docs suggest, but this works.
import Kerberos from "kerberos";
const service = "HTTP/[email protected]";
Kerberos.initializeClient(service, {}, (err, client) => {
if (err) throw err;
client.step('', (err, token) => {
if (err) throw err;
console.log(btoa(token)); // Base64-encoded service ticket
// Send this ticket to the server
});
});
If you see a replay error, it means the ticket was already cached. Just use a new one.
import Kerberos from "kerberos";
// Point Kerberos to the keytab file
process.env.KRB5_KTNAME = "/path/to/http.keytab";
const serviceTokenFromClient = "base64TokenFromClient";
const kerberosServer = await Kerberos.initializeServer("[email protected]");
const responseToken = await kerberosServer.step(serviceTokenFromClient);
console.log(responseToken);
if (kerberosServer.username) {
console.log(kerberosServer.username);
}