Вот некоторая информация и рекомендации.
Возможно ли это?Да.
Пакет Nodejs Radius: https://www.npmjs.com/package/radius Пакет Nodejs OTP: https://www.npmjs.com/package/otplib
Пример использования пакета радиуса для OTP: https://github.com/mcguinness/simple-radius-server
Youдолжен иметь возможность разветвить пример и изменить его для использования пакета OTP для генерации токенов OTP.
Другая возможность - развернуть FreeIPA в контейнере Docker, а затем использовать ldapjs для аутентификации на контейнере FreeIPA с узла.,См. Код ниже для примера того, как выполнить аутентификацию для FreeIPA с помощью ldapjs.
const LDAP = require('ldapjs');
class LDAPAuth {
constructor({url, base, uid}) {
this.errorCount = 0
setInterval(()=>this.errorCount = 0, 10000)
let self = this
function createLdap() {
self.ldap = LDAP.createClient({url})
.on('error', (error)=> {
console.error('Error in ldap',error)
self.errorCount++
if (self.errorCount > 20) {
console.error('Too many errors! Giving up...')
process.exit()
} else {
createLdap()
}
})
}
createLdap()
this.base = base
this.uid = uid
}
authenicate({username, password, count = 0}) {
let dn = `${this.uid}=${username},${this.base}`
if (count > 5) {
return Promise.reject('Failed to authenticate with LDAP!')
}
return new Promise((resolve, reject)=> {
this.ldap.bind(dn, password, (err, res) => {
if (err) {
if (err && err.stack && err.stack.indexOf(`${this.url} closed`) > -1) {
count++
// wait 1 second to give the ldap error handler time to reconnect
return setTimeout(()=>resolve(this.authenicate({username, password})), 2000)
}
console.error('ldap error', err)
reject(err)
}
if (res) resolve()
else reject()
})
})
}
}
module.exports = LDAPAuth
примечание: у примера кода есть проблемы, и я бы не стал его так писать сейчас, но уже несколько лет работает хорошо, поэтому не буду его трогать, пока не понадобитсявозникает.