Node.js NTLM Client (Legacy)
raw JSON →This package, `node-ntlm-client` at version 0.1.2, provides a client-side implementation for NTLM and NTLMv2 authentication in Node.js environments. It exposes functions for generating NTLM Type 1 and Type 3 messages, and decoding Type 2 messages, enabling developers to implement the NTLM handshake manually. It also includes a `request` convenience function that relies on the now-deprecated `request` HTTP client library. This package has seen no updates in approximately ten years and is considered abandoned, making it unsuitable for new projects. Modern alternatives typically use native Node.js `http`/`https` modules or other maintained HTTP clients, often with fewer external dependencies and better support for contemporary Node.js versions and language features like ESM.
Common errors
error Cannot find module 'request' ↓
request dependency explicitly: npm install request. However, it is highly recommended to avoid the deprecated request function and instead use the core NTLM message functions with a modern HTTP client. error TypeError: createType1Message is not a function ↓
require syntax: const { createType1Message } = require('ntlm-client');. Warnings
breaking The package includes a convenience `request` function that internally uses the `request` npm package, which has been deprecated since 2019 and is no longer maintained. Using this function may lead to security vulnerabilities or compatibility issues with newer Node.js versions. ↓
deprecated The `node-ntlm-client` package appears to be abandoned, with no updates in approximately a decade. This means it likely lacks support for newer Node.js features, security patches, or bug fixes, making it a poor choice for ongoing development. ↓
gotcha NTLM authentication itself is considered less secure than Kerberos and is being phased out by Microsoft. Relying on NTLM may introduce security risks and compatibility challenges with modern enterprise environments. ↓
Install
npm install node-ntlm-client yarn add node-ntlm-client pnpm add node-ntlm-client Imports
- createType1Message wrong
import { createType1Message } from 'ntlm-client';correctconst { createType1Message } = require('ntlm-client'); - decodeType2Message wrong
import decodeType2Message from 'ntlm-client';correctconst { decodeType2Message } = require('ntlm-client'); - createType3Message wrong
import * as ntlmClient from 'ntlm-client';correctconst { createType3Message } = require('ntlm-client');
Quickstart
const { createType1Message, decodeType2Message, createType3Message } = require('ntlm-client');
const http = require('http'); // Using native http for demonstration
const NTLM_SERVER_URL = process.env.NTLM_SERVER_URL ?? 'http://localhost:8080/protected';
const USERNAME = process.env.NTLM_USERNAME ?? 'user';
const PASSWORD = process.env.NTLM_PASSWORD ?? 'pass';
const WORKSTATION = process.env.NTLM_WORKSTATION ?? require('os').hostname();
const DOMAIN = process.env.NTLM_DOMAIN ?? '';
async function performNtlmHandshake() {
let type1Msg = createType1Message(WORKSTATION, DOMAIN);
console.log('Sending Type 1 message...');
// Step 1: Send Type 1 message
let response1 = await sendHttpRequest(NTLM_SERVER_URL, 'GET', { 'Authorization': `NTLM ${type1Msg}` });
if (response1.statusCode === 401 && response1.headers['www-authenticate']) {
const wwwAuthenticateHeader = response1.headers['www-authenticate'];
const type2Match = wwwAuthenticateHeader.match(/NTLM (.*)$/);
if (type2Match && type2Match[1]) {
console.log('Received Type 2 message. Decoding...');
let type2Msg = decodeType2Message(type2Match[1]);
let type3Msg = createType3Message(type2Msg, USERNAME, PASSWORD, WORKSTATION, DOMAIN);
console.log('Sending Type 3 message...');
// Step 2: Send Type 3 message
let response2 = await sendHttpRequest(NTLM_SERVER_URL, 'GET', { 'Authorization': `NTLM ${type3Msg}` });
if (response2.statusCode === 200) {
console.log('NTLM authentication successful!');
console.log('Response body:', response2.body.toString().substring(0, 100) + '...');
} else {
console.error('NTLM authentication failed at Type 3 stage. Status:', response2.statusCode);
}
} else {
console.error('No NTLM Type 2 message found in WWW-Authenticate header.');
}
} else if (response1.statusCode === 200) {
console.log('No NTLM authentication required. Request successful.');
console.log('Response body:', response1.body.toString().substring(0, 100) + '...');
} else {
console.error('Initial request failed or NTLM not initiated. Status:', response1.statusCode);
}
}
function sendHttpRequest(url, method, headers) {
return new Promise((resolve, reject) => {
const client = http.request(url, { method, headers }, (res) => {
let body = [];
res.on('data', (chunk) => body.push(chunk));
res.on('end', () => {
resolve({ statusCode: res.statusCode, headers: res.headers, body: Buffer.concat(body) });
});
});
client.on('error', reject);
client.end();
});
}
performNtlmHandshake().catch(console.error);