0

First off, thank you for viewing/helping with this.

I am trying to use the initializeClient function in the kerberos package from npm in Node. My goal is to be able to make requests to our internal API.

const kerberos = require('kerberos')

var company = 'company'
var service = `HTTP/internal.${company}.com@SERVER.${company.toUpperCase()}.COM`
var options = { principal: `firstname@SERVER.${company.toUpperCase()}.COM` }

kerberos.initializeClient(service, options, (err, details) => {
    console.log(details)
})

The response that comes back is:

KerberosClient {
  contextComplete: false,
  responseConf: 0,
  response: null,
  username: null
}

From what I can tell with how this functions works, you pass it the service, the options, which includes the principal, and a call back function.

Seems that the function is working but no data is returned. I've also tried passing an empty object as the options which looks like it would then just extract the current ticket from the machine, which is preferred.

I am running this on macOS 10.14 with Node v12.4.0. I've already installed krb5 from homebrew.

Questions are, why is this not returning anything expected (not yet sure what is expected) and is this the correct path to be able to make negotiate requests using Kerberos tickets?

Thanks again!

  • One thing to mention, when I do `kdestory` in my terminal, the response comes back as just **null** and when I do `kinit` it returns the response above. This means that the function for initializeClient does indeed see my keytab file on my machine. – rubberfishstudios Nov 13 '19 at 18:21

1 Answers1

0

So, the result was expected. I wasn't aware of the fact that you had to make any unauthorized request against our server to get back the www-negotiate header. Then you can use the string provided in the details with the step() function.

const request = require('request')
const kerberos = require('kerberos')
const {hostname} = require('./env')
const service = `HTTP@${hostname}`
const url = `https://${hostname}`

// Creates a Kerberos token and exchanges for an XSRF token.
function getXSRF() {
  return new Promise((resolve, reject) => {
    request.get(url, () => {
      const mechOID = kerberos.GSS_MECH_OID_KRB5

      // Send a request un-authenticated
      kerberos.initializeClient(service, { mechOID }, (err, client) => {
        if (err) {
          reject(err)
        } else {

          // Generate the first Kerberos token
          client.step('', (err, kerberosToken) => {
            if (err) {
              reject(err)
            } else {
              var options = {
                url, 
                headers: { 
                  Authorization: `Negotiate ${kerberosToken}`
                }
              }
      
              // Attach the Kerberos token and resend back to the host
              request.get(options, (err, response) => {
                if (err) {
                  reject(err)
                } else {
                  var result = {xsrf: JSON.parse(response.body).xsrf, kerberos: kerberosToken}
                  resolve(result)
                }
              })
            }
          })
        }
      })
    })
  })
}

module.exports = {
  getXSRF: getXSRF
}

The example where this was located was found here: https://github.com/mongodb-js/kerberos/blob/master/test/kerberos_tests.js#L79