Giter VIP home page Giter VIP logo

node-expose-sspi's Introduction

Node expose sspi

Expose the Microsoft Windows SSPI (SSP Interface) to Node.js®.

Use cases:

  • NTLM and Kerberos SSO authentication, both server and client inside a private windows organization network, for instance an ERP in a private company.
  • Active Directory access to users for detailed info.

Requirements: Microsoft Windows OS, NodeJS version >=12.16.1. Architecture: x64 or ia32.

Reference

Install

license npm version sponsor

Just do:

npm i node-expose-sspi

Note: There is a prebuilt binary node addon that will be installed.

Usage

SSO Authentication server use case

mkdir myproject
cd myproject
npm init -y
npm i express
npm i node-expose-sspi

Make an express web server by doing the server.js file:

const express = require('express');
const { sso } = require('node-expose-sspi');

const app = express();
app.use(sso.auth());

app.use((req, res, next) => {
  res.json({
    sso: req.sso,
  });
});

app.listen(3000, () => console.log('Server started on port 3000'));
node server.js

Browser on http://localhost:3000

{
  "sso": {
    "method": "NTLM",
    "user": {
      "domain": "JLG",
      "name": "jlouis",
      "displayName": "Jean-Louis P. GUÉNÉGO",
      "groups": [
        "JLG\\Domain Users",
        "\\Everyone",
        // ...
      ],
      "sid": "S-1-5-21-2022955591-1730574677-3210790899-1103",
      "adUser": {
        // adUser filled only if Active Directory is reachable.
        // ...
        "givenName": ["Jean-Louis"],
        "sn": ["GUÉNÉGO"],
        "c": ["FR"],
        "l": ["TORCY"],
        "postalCode": ["77200"],
        "title": ["IT Consultant"],
        "description": ["My microsoft domain account for demonstrating SSO"]
      }
    }
  }
}

Note: To read JSON file on Chrome, you should use the JSON Formatter Chrome Extension.

Command line client:

  • Git Bash: curl --negotiate -u : http://localhost:3000 -b cookie.txt
  • Powershell: Invoke-WebRequest -uri http://localhost:3000 -UseDefaultCredentials

To know more, you can follow the SSO Reference Manual.

SSO Authentication client use case

See the complete example

Account context status

const { sso } = require('node-expose-sspi');

The sso object has following functions to help you:

  • sso.hasAdminPrivileges(): check if user has administrator privileges. A user can be administrator, but when starting a process, it does not have administrator privileges by default. To have them, the process needs to be started as an administrator. See Microsoft documentation about it.
  • sso.isOnDomain(): check if the computer has joined a domain.
  • sso.isActiveDirectoryReachable(): check if the Active Directory domain controller is reachable.

API

Fully detailed API document.

Browsers

Chrome

No conf. It just works.

Firefox

Unlike Chrome, NTLM and Kerberos are not activated by default in Firefox. To make it working, you need to follow these steps:

  1. Navigate to the URL about:config.
  2. Click past the warning of harmful consequences.
  3. Type negotiate-auth into the filter at the top of the page, in order to remove most of the irrelevant settings from the list.
  4. Double-click on network.negotiate-auth.trusted-uris. A dialogue box for editing the value should appear.
  5. Enter the required hostname(s) and/or URL prefix(es) then click OK. For the above example, it is http://localhost:3000

More detailed info here.

Edge

Edge does not require any configuration. But the browser ask the credentials to the user each time it is started.

IE11

IE11 does not require any configuration. Be careful it does not open JSON files in a simple way.

Typescript

This module is ready to be used with both typescript and javascript. No need extra typings.

Typescript example

Authentication protocols

Kerberos

Kerberos is recommanded for production running. For running with Kerberos protocol, both client and server needs to be joined on a Windows Domain.

3 conditions must be met for running Kerberos:

  • The node server, running node-expose-sspi needs to be run as a domain user with service principal name (SPN) declared in Active Directory.
  • The client browser needs to be run on a windows domain account.
  • The website url needs to be declared in a white list of intranet website.

You can find more detail in the Kerberos dedicated documentation.

NTLM

If you are not on a Windows Domain, node-expose-sspi will use the NLTM authentication protocol.

If both the server and the client are on a Windows Domain, NTLM will be used if the Kerberos conditions are not met. See the Kerberos chapter of this README.

The NTLM protocol is less secure than Kerberos and not secure at all if you are not under an HTTPS connection. This is because both login and password hash go on the HTTP request, just encoded in base64...

Another thing bad in NTLM is that browsers sometimes popup a dialog box to ask credentials to the user. Your users don't like that. This is a bad user experience.

Authentication error analysis

If you encounter error, please read this document before submitting an issue.

Production running

Performance

You should avoid to use the Negotiate protocol each time a user access an authenticated resources, because it may take times.

Just use the Negotiate protocol once with sso.auth() on a specific connection url, and then put a session id cookie associated with the req.sso object. Please see this example.

Server behind a reverse proxy

Example: node server behind an IIS proxy

Examples

To run the examples, just clone this project.

git clone https://github.com/jlguenego/node-expose-sspi.git
npm i
cd node-expose-sspi
cd examples
cd <***example-name***>

Look also at the README.md of the example.

Examples :

Development

As a prerequisites, you need node-gyp and a C++ toolchain installed on your environment.

If you did not installed node-gyp and the C++ toolchain, please open a PowerShell command line as an administrator and do :

npm i -g windows-build-tools

To compile the native node module, do the following:

git clone https://github.com/jlguenego/node-expose-sspi.git
cd node-expose-sspi
npm run build
npm run test

There are 2 dev areas :

  • C++ code: run npm run dev to watch the modifications and recompile ASAP.
  • Typescript code: run npm run build:tsw to recompile while watching.

All tests are done with mocha.

The module debug is used for printing some debug info.

Hardware architecture

To both compile ia32 and x64, run the npm run build:arch command.

TODO

Any idea of new features ? Please tell me and raise an issue. 😊

  • write a loopback example
  • write a nestjs example
  • write a medium article
  • Integrate with passport?
  • Test with 10000 users.
  • UTF8 everywhere

Scenario:

  • linux trial.

Thanks

Thanks to all the people who wrotes the npm modules required by this project.

And a very special thanks to the authors of the node-sspi project that helped me writing this one. I considere node-sspi to be the father of node-expose-sspi.

Thanks also to people raising issues to improve the quality of this module.

Sponsoring

This library design aims to be used in production, in private company environment, doing business, using Microsoft Windows.

To help maintaining it, you can sponsor me with github.

Author

Jean-Louis GUENEGO [email protected] (http://jlg-consulting.com/)

You may participate to complete this project. You can improve this doc, or check the code (memory leak, etc.), create new usefull business cases, etc.

Contributors are welcome!

node-expose-sspi's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

node-expose-sspi's Issues

Client is silently failing at line 209

const clientCred = sspi.AcquireCredentialsHandle(credInput);

When I'm debugging, this line triggers my node program to terminate with an error but does not give any error message.

I'm trying to authenticate a node app, I'm following the example pretty much to a T.

I do not have an issue when trying to hit endpoints in my browser, but from a node cli I am struggling.

When I log out credInput, it is


{
    packageName: 'Negotiate',
   credentialUse: 'SECPKG_CRED_OUTBOUND'
}

Does this module work only with Miscrosoft Windows?

I have a error:
/home//fbserver/node_modules/node-expose-sspi/dist/index.js:11
throw new Error("The module 'node-expose-sspi' can only work on Microsoft Windows platform.");
^

Error: The module 'node-expose-sspi' can only work on Microsoft Windows platform.
at Object. (/home/bastrikov_da/fbserver/node_modules/node-expose- sspi/dist/index.js:11:11)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object. (/home/bastrikov_da/fbserver/server.js:4:17)
at Module._compile (internal/modules/cjs/loader.js:778:30)

What should I do if the server NodeJS runs on Linux (CentOS)?

Error handling for invalid login credentials for whitelist popup

Whenever whitelist has not been applied and the browser makes a user insert their username and password in the pop up, if the credentials are invalid, the HTML serves the error "BadRequestError: Error while doing SSO: AcceptSecurityContext error: SEC_E_LOGON_DENIED".

  • Question 1: Is there a way to recover and properly handle this error, so it does not serve this page?
  • Question 2 (Separate but slightly related): If the whitelist pop up appears, is there a way for an error to appear, so that it can be skipped over or handled in a different way?

BadRequestError: Error while doing SSO

Working on running a simple script with express and node-expose-sspi on a Windows OS. When I use a client to ping the server, I get the following error: "BadRequestError: Error while doing SSO". The goal is to use Kerberos.

Also, using Google Chrome to do this and have whitelisted the domain.

32-bit Compatibility

I face an error when running the library with nodejs 32-bit, please see console response: "\node_modules\node-expose-sspi\lib\api.node is not a valid Win32 application."

Is it possible to update the library, so that it is compatible with a 32-bit environment (nodejs and Windows OS)?

BadRequestError: Malformed authentication token NTLM <token>

Hi @jlguenego,

Sorry for spamming your issue tracker, but was able to tweak my web server differently, so I gave it another shot.

What is happening I'm getting the following error in IE 11.3630.x:

BadRequestError: Malformed authentication token NTLM <token>
    at Object.<anonymous> (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:100:80)
    at step (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:33:23)
    at Object.next (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:14:53)
    at C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:8:71
    at new Promise (<anonymous>)
    at __awaiter (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:4:12)
    at C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:86:31
    at C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:180:15
    at Layer.handle [as handle_request] (C:\<path>\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\<path>\node_modules\express\lib\router\index.js:317:13)

But I'm able to authenticate myself from the very same machine in the terminal by:

Invoke-WebRequest -uri <URL> -UseDefaultCredentials

Could you please advise what went wrong?

authenticated status

This isn't a bug report so much as a question. I am getting a 400 status back, but I think I am getting authenticated correctly, I'm just not talking to the service the right way. I am using your library to have node connect to a 'Business Central' OData instance.

I'm running node 12 on windows 10 and my machine is NOT on the same domain as the server.


var { sso } = require('node-expose-sspi');

var url = 'http://abc123host.internal:7048/BL_BC140CU01/OData/$metadata';

( async ()=> {

try {

    sso.auth({
        useOwner: false,
        useActiveDirectory: true,
        useCookies: false,
        domain:'JM',
    }) ;

    const client = new sso.Client();
    client.setCredentials ('domain','user', 'pass');
    client.setSSP('NEGOTIATE');
  
 console.log( sso.getStatusInfo() );

 const resp1 = await  client.fetch(url) ;
 
console.log('resp1', resp1 );

}catch(e){
    console.log('#####ERR', e);
console.log(e);

}
})();


The 'Authorization: Negotiate TlRMTVNTUAACAAAACgAKADgAA......

makes me think it HAS authorized correctly. I would get a 401 back if it didn't I assume?

{ adminPrivileges: false, isOnDomain: false, domain: 'ZIPPY' }
node-expose-sspi:client start response.headers Headers {
[Symbol(map)]: [Object: null prototype] {
'content-length': [ '0' ],
server: [ 'Microsoft-HTTPAPI/2.0' ],
'www-authenticate': [ 'Negotiate' ],
date: [ 'Wed, 11 Nov 2020 20:08:20 GMT' ],
connection: [ 'close' ]
}
} +0ms
node-expose-sspi:client cookieList: {} +3ms
node-expose-sspi:client starting negotiate auth +0ms
node-expose-sspi:client input: {
credential: '0x0000015e432f07b0.0x0000022f3ad54eb0',
targetName: 'HTTP/qds-navmhwk03.JM.internal',
cbMaxToken: 48256,
targetDataRep: 'SECURITY_NATIVE_DREP'
} +2ms
node-expose-sspi:client first requestInit.headers {
Authorization: 'Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAGFKAAAADw=='
} +5ms
node-expose-sspi:client first response.headers Headers {
[Symbol(map)]: [Object: null prototype] {
'content-length': [ '0' ],
server: [ 'Microsoft-HTTPAPI/2.0' ],
'www-authenticate': [
'Negotiate TlRMTVNTUAACAAAACgAKADgAAAAVgoniv88d9Dcm7LAAAAAAAAAAALgAuABCAAAACgBjRQAAAA9RAEkAWABBAFMAAgAKAFEASQBYAEEAUwABABoAUQBEAFMALQBOAEEAVgBNAEgAVwBLADAAM
wAEABwAcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAMAOABRAEQAUwAtAE4AQQBWAE0ASABXAEsAMAAzAC4AcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAUAHABxAGkAeABhAHMALgBpAG4AdABlAHIAbgB
hAGwABwAIACjE+2ZmuNYBAAAAAA=='
],
date: [ 'Wed, 11 Nov 2020 20:08:20 GMT' ],
connection: [ 'close' ]
}
} +199ms
node-expose-sspi:client cookieList: {} +3ms
node-expose-sspi:client other requestInit.headers {
Authorization: 'Negotiate TlRMTVNTUAADAAAAGAAYAHwAAAB+AX4BlAAAAAoACgBYAAAAEAAQAGIAAAAKAAoAcgAAABAAEAASAgAAFYKI4goAYUoAAAAPKPaMbj/9si8k8JkIau909lEAaQB4AGEAcwBRAH
cAYQBuAHQAaQBmAHkAWgBJAFAAUABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ/SXVc3MBAOOkU9xngqu9ABAQAAAAAAACjE+2ZmuNYBnJZAJ/rnoKkAAAAAAgAKAFEASQBYAEEAUwABABoAUQBEAFMALQBOAEEA
VgBNAEgAVwBLADAAMwAEABwAcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAMAOABRAEQAUwAtAE4AQQBWAE0ASABXAEsAMAAzAC4AcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAUAHABxAGkAeABhAHMALg
BpAG4AdABlAHIAbgBhAGwABwAIACjE+2ZmuNYBBgAEAAIAAAAIADAAMAAAAAAAAAABAAAAACAAAEbEIFqOY7gLT8Z0cXmgo5IMZz00azmjLMcq/LbdXof8CgAQAAAAAAAAAAAAAAAAAAAAAAAJAEIASABUAFQAUAAv
AHEAZABzAC0AbgBhAHYAbQBoAHcAawAwADMALgBxAGkAeABhAHMALgBpAG4AdABlAHIAbgBhAGwAAAAAAAAAAAArJ4CcTLZtoXOXUllFUUMP'
} +3ms
node-expose-sspi:client other response.headers Headers {
[Symbol(map)]: [Object: null prototype] {
'content-length': [ '0' ],
server: [ 'Microsoft-HTTPAPI/2.0' ],
date: [ 'Wed, 11 Nov 2020 20:08:20 GMT' ],
connection: [ 'close' ]
}
} +262ms
node-expose-sspi:client cookieList: {} +3ms
node-expose-sspi:client handleAuth: end +1ms
resp1 Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
readable: true,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: true,
_transformState: [Object],
[Symbol(kCapture)]: false
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: 'http://qds-navmhwk03.JM.internal:7048/BL_BC140CU01/OData/$metadata?$format=json',
status: 400,
statusText: 'Bad Request',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
}

Security error when using a webpack devServer proxy

Describe the bug
The setup: I have a front end dev environment using Svelte and webpack running at port 8080 that has a proxy to my express server running at port 3000. I originally used your Vue example and converted it for Svelte. I am able to connect with SSO from localhost:8080 up to version 0.1.52.

At version 0.1.53, when I try to connect with SSO at localhost:8080 via the proxy server I am getting the following error:

Error: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid

at C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\node-expose-sspi\src\sso\auth.ts:132:44
at C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\node-expose-sspi\src\sso\auth.ts:226:7
at Layer.handle [as handle_request] (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\index.js:275:10)
at Immediate._onImmediate (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express-session\index.js:495:7)

statusInfo: {
adminPrivileges: false,
isOnDomain: true,
domain: 'MYDOMAIN',
isActiveDirectoryReachable: true
}

messageType: NTLM_AUTHENTICATE_03
UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid

at C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\node-expose-sspi\src\sso\auth.ts:224:25
at C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\node-expose-sspi\src\sso\auth.ts:226:7
at Layer.handle [as handle_request] (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express\lib\router\index.js:275:10)
at Immediate.<anonymous> (C:\Users\brian.casey\Desktop\projects\ap-review-nes-test\node_modules\express-session\index.js:495:7)

My SSO connect is as follows :
app.get("/action/connect-with-sso", sso.auth({useSession: true}), (req, res) => {
if (!req.sso) {
delete req.session.sso;
res.status(401).end();
return;
}
req.session.sso = req.sso;
res.json({ user: req.sso.user });
});

My session is configured as follows:
app.use(
session({
secret: apSecret, // env variable
resave: false,
saveUninitialized: true,
name: 'express-sso-session'
})
);

I also have my express server set up to serve my public directory at localhost:3000 (for when I move this to production) so I can get to my app there as well. If I start the server and try to get to the app via 8080 I get the security error. If I go to the app at localhost:3000 and then try again at 8080 it then works at 8080.

Expected behavior
I expect to be able to use a proxy server from my front end dev environment and not get the security error.

Environment version:

  • OS: Windows 10 Pro version 20H2 build 19042.508
  • Browser version: Chrome 88
  • Node version and architecture: 14.15.5

Please indicates also:

  • Are you on a Windows domain ? yes
  • Can you reach the domain controller ? yes
  • Do your session have admin privileges ? no
  • Which authentication protocol ? Unknown

Tried fetch for Kerberos

I tried using the code to process a Kerberos negotiation but the base64 string created by the InitializeSecurityContext (with targetDataRep = SECPKG_CRED_OUTBOUND) and the AcquireCredentialsHandle (with targetDataRep = SECURITY_NATIVE_DREP) is not working.
I creates a string value but the server rejects it.
I tried with a different node component (but compiled for a node version that is not convenient for me 11.15.0) and it works against the same address, an SVC .net web service hosted in IIS with Windows Authentication with the Provider = Negotiate.
I tried against without the SSL certificate, this component does not work but the other component for node 11.15.0 does, so I think the Kerberos values used to generate the base64 string are wrong.

Logon dialog prompt when accessing server from IP on local machine or other machines on network?

Hi,

We have been trying this module running the react-sample.
Environment: Windows Domain running NTLM

Dialog prompt: Steps to reproduce

  1. Start backend server and frontend
  2. Start Chrome (83.0.4103.97 - running on windows) or IE 11
  3. Access backend server through IP from local machine. http://xx.xxx.xx:3000
  4. Or access backend server from another machine on the network
  5. Login prompt is presented to the user

IS this expected behavior. I would expect the user to just be logged in throug SSO. Using the same browser to access sharepoint sites on the same domain works with SSO - without having to log in.

**SSO working as expecting **

  1. Start backend server and frontend
  2. Start Chrome (83.0.4103.97 - running on windows)
  3. Access backend server through localhost from local machine. http://localhost:3000
  4. User is getting logged in as expected

Kind regards Morten

request: add express-session support

Adding express session with options useSession: false (by default for backward compatibility).

useSession: true

if no req.session.sso then compute req.sso then copy it to req.session.sso.

if req.session.sso then do not run Negotiate protocol.

Invalid token

I get this error when I try to call InitializeSecurityContext(arg) with the following arg:

{
  "credential": "XXXXXXX",
  "targetName": "HTTP/<hostname>",
  "cbMaxToken": 65791,
  "serverSecurityContext": {
    "SecBufferDesc": {
      "ulVersion": 0,
      "buffers": [
        {}
      ]
    }
  },
  "contextHandle": "XXXXXXXXX",
  "targetDataRep": "SECURITY_NATIVE_DREP"
}

Exception

Error: Cannot InitializeSecurityContext: secStatus = (error code: 0x80090308) The token supplied to the function is invalid

Request for support of Node.Js >= 12.14.1 instead of >= 12.16.1

Hi,

I'm trying to use your node-expose-sspi from my VSCode Extension, but it fails import because of the required Node.Js version.
VSCode bundles its own node version (12.14.1) and that one is too old for node-expose-sspi

When running directly from the commandline with node it works perfectly, so it would be really nice to be able to use it from my VS Code Extension.

I tried forking the repo and building it myself, but failed big time :-(

Thanks

Cannot access SSO with copluter host name

Hi,
Fisrt I want to thank you for your hard work supporting this.

I need your help with my issue:

  1. I've implemented your example on one of our network servers. (windows server 2016)
  2. When I try to get sso login with IP address everything works fine.
  3. But when I try to get sso login with computer host address, I'm getting a popup window says enter login credentials.

What Im missing?

One note:
If I continuing by clicking on cancel, I'm getting following exception on node console:

statusInfo: {
adminPrivileges: true,
isOnDomain: true,
domain: 'NTNET',
isActiveDirectoryReachable: true
}
messageType: Kerberos_1
UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid

BR
Avshalom

Koa sample is not working

Running the simple koa sample using [email protected] is failing with 404 error and Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.

The Active Directory and authentication is working: I can get data into ctx.req.sso. Unfortunately everything after the handshake is broken with koa responding with 404, sending headers that conflicts with the setHeaders for 'WWW-Authenticate'.

Your PC will automatically restart in one minute - SECURITY_STATUS incorrect (<0): (error code: 0x80090304) The Local Security Authority cannot be contacted

I have installed my application on the windows server and when I try to access the application from another system using the hostname of the server. I am getting below error

`Error: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090304) The Local Security Authority cannot be contacted

 at Object.<anonymous> (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:152:60)
at step (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:33:23)
at Object.next (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:14:53)
at fulfilled (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:5072) UnhandledPromiseRejectionWarning: Error: GetUserNameEx: error first call. (error code: 0x000006ba) The RPC server is unavailable.

 at Object.getDefaultDomain (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\domain.js:11:26)
at Object.getStatusInfo (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\status.js:8:29)
at Object.<anonymous> (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:202:64)
at step (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:33:23)
at Object.next (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:14:53)
at fulfilled (C:\inetpub\wwwroot\code\api\node_modules\node-expose-sspi\dist\sso\auth.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:5072) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:5072) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.`

Your PC will automatically restart in one minute and PC is getting restarted every time I access it.

Version : 0.1.39

Please let me know for any further information.

Regards,
Kiran

Document behavior with hostname redirection

In order to authenticate the server hostname must be a specific value (I have only tested "http://localhost:3000/"). If I try to authenticate with http://sspi.auth.local:3000/ (where sspi.auth.local redirects to localhost in the windows hosts file) then the authentication fails.

I guess this is by the design of Kerberos and/or NTLM that the browser (client) must only generate correct credentials for a proper server name. It just seems like this could be better documented.

I encountered the problem when testing a server with HTTPS, since many solutions suggest setting the fully qualified domain name specified in the certificate to a form like "[testname].local".

After some investigation I found that the client can be called with setTargetName("localhost") even when connecting to http://sspi.auth.local:3000 and get the correct behavior.

Unable to use package in TS express application

Describe the bug
Build fails when I try to use this in a TS+Express project. An assumed member of Express has been used in v0.1.44. Interestingly, the output does appear in dist so you can run the server -- puzzling 🤔

My intention is to use this in a Nestjs project wherein the same error appears and we can't run the server.

To Reproduce

Try to build this vanilla express example project using npm run build && npm run start.

Try to build/run this vanilla nestjs example.

Trace


> [email protected] build C:\Users\abahadur\msft\express-simple-ts-example
> tsc -p .

node_modules/node-expose-sspi/src/sso/interfaces.ts:20:23 - error TS2694: Namespace 'global.Express' has no exported member 'Session'.

20     session?: Express.Session;
                         ~~~~~~~


Found 1 error.

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] build: `tsc -p .`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\abahadur\AppData\Roaming\npm-cache\_logs\2020-10-20T18_55_05_832Z-debug.log

Expected behavior
The build to sucees

Environment version:

  • OS: Windows 10 Pro version 1903 x64
  • Node version and architecture: 12.19.0 64bit

Additional context
I think the fix is already merged in master @ 6f991bf and we probably just need to cut out a patch release.

I tried tp build node-expose-sspi but there seems to be some issue with my C++ env.

BadRequestError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect

I'm getting the following error:

BadRequestError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid

at Object.<anonymous> (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:175:54)

at step (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:33:23)

at Object.next (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:14:53)

at C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:8:71

at new Promise (<anonymous>)

at __awaiter (C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:4:12)

at C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:86:31

at C:\<path>\node_modules\node-expose-sspi\dist\sso\auth.js:180:15

at Layer.handle [as handle_request] (C:\<path>\node_modules\express\lib\router\layer.js:95:5)

at trim_prefix (C:\<path>\node_modules\express\lib\router\index.js:317:13)

Environment:

OS: Windows Server 2016
Node: 12.16.2
Version: 0.1.27

Code Outline:

const dotenv = require('dotenv');
const express = require('express');
const { sso } = require('node-expose-sspi');
dotenv.config();
const app = express();
app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Cache-Control');
    next();
});
app.use(sso.auth());
app.use(express.json());
app.set('port', process.env.PORT || 3003);
app.get('/api/endpoint', (req, res) => {
...

Hitting /api/endpoint directly in Chrome will result in the following error.

Expose more user info

Hi this is not really urgent but i suggest to expose more AD user info more such as Firstname, Surname :) really loves this module

BadRequestError: Accept SecurityContext

I am running a simple script using the latest version and as you mentioned previously, that sometimes I need it to initialize and then rerun it for it to actually work.

I followed your instructions, and this is what happened (Running 32bit nodejs on Windows 64bit OS):

  1. Ran Script
  2. Go to localhost:3000
  3. Receive error "BadRequestError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect(<0): (error code: 0x80090308) The token supplied to the function is invalid"
  4. Refresh the page to go to localhost:3000
  5. Receive status code 200 and successfully retrieve AD information via "NTLM". In addition to this success message, I receive a different error message:
    "BadRequestError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect(<0): (error code: 0x80090301) The handle specified is invalid".

I am not sure why I am receiving two responses at once (success + error message).

Please note that with the previous version of the library, this would not occur. It would either consistently error or it would work upon initially running the script.

NTLM Authentication doesn't seem to work in node.js

The NTLM authentication doesn't seems to work at all in nodejs (12.19.0)

In Windows 10 Pro x64 built in IIS configured to accept NTLM (works with any browser).

To reproduce:
const sso = require("node-expose-sspi");
const x = new sso.Client();
x.setSSP("NTLM");
x.setCredentials("", "username", "password");
x.fetch("https://localhost/").then(r =>console.log(r.status)).catch(e => console.error(e));

I've tried to access other Microsoft webservers also, the result is the same.
I've set env variable DEBUG=node-expose-sspi:*. but got no more log.
I've debugged the program, everything seems to be alright, but after sending NTLM 3 type message IIS refuses it with another 401 HTTP status code instead of responding 200.

I've compared the parsed NTLM messages (browser and nodejs) the only significant difference I see is that node-expose-sspi's NTLM 3 message doesn't containts Session Key member while the browser's version has a 16 bytes long session key. (Negotiate Key Exchange also missing of course)

OS: Windows 10 Pro version 19041.572 x64]
Browser version: Chrome 86.0.4240.111
Node version and architecture: 12.19.0 64 bits

  • Are you on a Windows domain: no
  • Can you reach the domain controller: no
  • Do your session have admin privileges: no
  • Which authentication protocol: NTLM

make typescript strict

update tsconfig.json in order to have the 'strict' option set to true. Update the ts code in order to clean it.

Facing issue while building the app using webpack

When building the app using webpack, the build is successful but, I am seeing the below warning

WARNING in ./node_modules/node-expose-sspi/lib/api.js 2:17-34
Critical dependency: the request of a dependency is an expression
@ ./node_modules/node-expose-sspi/dist/index.js
@ ./app.js

When I start the application, I am receiving the below error message.

D:\Sources\API\src\dist\app.js:235101
throw e;
^

Error: Cannot find module './arch/x64/api.node'
at webpackEmptyContext (D:\Sources\API\src\dist\app.js:235099:10)
at Object. (D:\Sources\API\src\dist\app.js:15131:43)
at webpack_require (D:\Sources\API\src\dist\app.js:20:30)
at Object. (D:\Sources\API\src\dist\app.js:29199:10)
at webpack_require (D:\Sources\API\src\dist\app.js:20:30)
at Object. (D:\Sources\API\src\dist\app.js:123324:13)
at webpack_require (D:\Sources\API\src\dist\app.js:20:30)
at D:\Sources\API\src\dist\app.js:84:18
at Object. (D:\Sources\API\src\dist\app.js:87:10)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND'
}

Later, when I wet ahead and changed the app.js file present in the below folder, I was able to get it working

\node_modules\node-expose-sspi\lib\api.js

Changed code: module.exports = require("./arch/"+ process.arch + "/api.node");

Here is the webpack configuration I am using.

webpack.config.js

const path = require('path');
// const { CleanWebpackPlugin } = require('clean-webpack-plugin');
var nodeExternals = require('webpack-node-externals');
module.exports = {
entry: {
app: './app.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
optimization: {
minimize: false
},
module: {
rules: [
{
test: /.node$/,
loader: 'node-loader'
}
]
}
// "plugins": [
// new CleanWebpackPlugin({protectWebpackAssets: false, cleanOnceBeforeBuildPatterns: !['./Web.config']})
// ]
}

Can you please let me know if their is any issue or suggest me if I am doing anything wrong

401 for static assets when serving react app

Hiho,

first and foremost: Awesome libarary!

I have a very weird error.
I have a node + express server.
I serve my react build directory like this:

app.use(express.static(path.join(__dirname, "client", "build")));

When I go to the site I see this error in the chrome console:

GET http://myserver/static/js/2.d0df15ed.chunk.js net::ERR_ABORTED 401 (Unauthorized)

When I disable sso.auth(): // app.use(sso.auth()); I don't get this error.

It's so weird, it's just for some random .chunk. files it seems.

Do you know what the problem might be? I really have no idea what the problem is.

I should propably also mention that I also set up some test api routes (that just sends json) and these work fine without error.
For example:

app.get("/api/me", (req, res) => {
  res.send(req.sso);
});

It's just when I serve the react-app and only some static files.

This is the project structure:

image

In the client folder there is the build folder and it's index.html. The index.html has links to the css and js files in static folder (like the defaults from create-react-app if you know that).

EDIT 1: I see I also get an error in the server console:

UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid

But only on the root route where I server react app. All other pure api routes work fine and sso work (for example me, shows my account and that it's using Kerberos).

EDIT 2: It seems that I get the error from above many times:

When I go to the site one time I get many requests, and many error messages. It's like it would check the credentials for all files I'm serving maybe? That would explain why sometimes the file in the error message is another one. Sometimes a chunk.css sometimes a chunk.js file? Is this package ready for also serving a client project? If not what would be an alternative way to achieve this?

I would be soooo grateful if you could help me out, because I'm building a nice tool for my company and it works so good, but this error is pulling my hair since 2 days :D

Thx so much @jlguenego

how to use the client?

Hi,

I created a Node script to connect to a web server (that is not a Express server and that I don't control), This webserver needs Kerberos authentication. On a page I'll receive a 401 code with a header www-authenticate that has the value Negociate. From there, can I use your sso.client to handle the authentication handshake with the server for me?

What I've done so far:

const request = require('request'); // the one I use for the other requests
const { sso } = require('node-expose-sspi');

async function run() {
[... do a few request then handle the response ...]
  if (response.headers['www-authenticate'] === 'Negotiate') {
      console.log("Start Kerberos Authentication");
      try {
        const { fetch } = sso.client;
        const res = await fetch(uri, {
          headers:headers // here I pass headers including 2 cookies: `JSESSIONID` and `PF`
        });
        console.log("Fetch completed"); // <- I never reach this point?!
        let resBody = await res.text();
        console.log(resBody);
      } catch(err) {
        console.log("ERROR => ",err);
      }
  }
}

Two issues here:

  1. I use https://httptoolkit.tech/javascript to intercept the requests and see what's going on: I can see that a request is done on behalf of your fetch, but I don't see any special headers or cookies that are sent (it just replicates my first request), so the server replies the same 401 with www-authenticate; Negociate than before… What I'm missing here?
  2. I never reach "Fetch Completed"… my Node script just stop?!

Merci !

Auth without middlewares support

Describe the bug
This is more a question than a bug.

So far we have used this lib with Fastify and it works perfectly. Since recently we are evaluating to migrate our HTTP/WS app to uWebSockets.js, which doesn't support middleware functions out-of-the box

How to use this lib without middleware?

To Reproduce

Example tried:

const { sso } = require('node-expose-sspi')
const uWS = require('uWebSockets.js')
const port = 4001


const authPromise = (ctx) => {
  return new Promise((resolve, reject) => {
    const next = (err) => {
      err ? reject(err) : resolve()
    }
    try {
      const auth = sso.auth({ useGroups: false, useSession: false })
      auth(ctx.req, ctx.res, next)
    } catch (e) {
      console.log(e)
    }
  })
}

uWS.App()
  .get('/api/auth', async (res, req) => {
       res.onAborted(() => {
          res.aborted = true
       })
       const ctx = { req, res }
       await authPromise(ctx)
       if (!res.aborted) {
           res.end(req.sso) // YIELDS nothing
       }
   })
  .listen(port, (token) => {
    if (token) {
      console.log('Listening to port ' + port)
    } else {
      console.log('Failed to listen to port ' + port)
    }
  })
})

Trace
only this log:

node-expose-sspi:auth no authorization key in header +0ms

then the response is ended with these headers:

Content-Length: 0
uWebSockets: 18
WWW-Authenticate: Negotiate

It seems to me that these headers should have been sent to the AD, not as final response to the browser.

How to work around this?

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Environment version:

  • OS: Windows 10 Pro version 1909 x64
  • Browser version: Chrome 9.0.4389.90
  • Node version and architecture: v15.11.0 x64

Please indicates also:

  • Are you on a Windows domain ? yes
  • Can you reach the domain controller ? yes
  • Do your session have admin privileges ? yes
  • Which authentication protocol ? NTLM
  • Active Directory, or local window policies that could impact the authentication. N/A

Additional context
Add any other context about the problem here.
N/A

Is there a way to do the AD auth without middleware support... e.g. via sequential async calls?

(req, res) => {
    // connect
    // get token
    // get user info
}

Thanks in advance.

Fasitify + CORS = no authorization key in header

Describe the bug
In this fastify setup:

const corOptions = {
origin: '*',
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
allowedHeaders: ['content-type', 'authorization', 'access-control-allow-origin', 'access-control-allow-credentials'],
credentials: true
}

await fastify
.register(require('middie'))
.register(require('fastify-cookie'))
.register(require('fastify-cors'), corsOptions)

await fastify
.use('/api/auth/login', require('cors')(corsOptions))

await fastify
.use('/api/auth/login', sso.auth({ useGroups: false, useOwner: false, useActiveDirectory: false }))

with this route:

const routes = {
authenticate: true,
method: 'GET',
url: '/api/auth/login',
schema: {
response: {
200: authSchema.login.response[200],
409: errorSchema.response[409],
500: errorSchema.response[500]
}
},
handler: authController.login
}

authController being an instance of:

class AuthController {
login (request, reply) {
reply.send(request.raw.sso ? request.raw.sso.user : { error: 'Unknown' })
}
}

await fastify
.decorate('authenticate', async (request, reply, done) => {
const handler = sso.auth({ useGroups: false, useOwner: false, useActiveDirectory: false })
await handler(request, reply, done)
})
.after(() => {
routes.forEach((route) => {
fastify.route(route)
})
})

fastify being started on localhost:3001.

When Accessed without cors:

http://localhost:3001/api/auth/login

Everything works fine.

However, when accessed from another app listening on port 3000, these trace logs can be found:

node-expose-sspi:schManager initCookie +0ms
node-expose-sspi:schManager cookie not found, so generating one +11ms
node-expose-sspi:auth cookieToken: NEGOTIATE_8946007805 +0ms
node-expose-sspi:auth no authorization key in header +0ms

To Reproduce

Fastify + CORs setup as described from above, doesn't work

Trace
node-expose-sspi:schManager initCookie +0ms
node-expose-sspi:schManager cookie not found, so generating one +11ms
node-expose-sspi:auth cookieToken: NEGOTIATE_8946007805 +0ms
node-expose-sspi:auth no authorization key in header +0ms

Expected behavior

Same as without CORS

Screenshots
N/A

Environment version:

  • OS: Windows 10 Pro version
  • Browser version: Chrome 86.0.4240
  • Node version and architecture: v15.1.0

Please indicates also:

  • Are you on a Windows domain ? yes
  • Can you reach the domain controller ? yes
  • Do your session have admin privileges ? no
  • Which authentication protocol ? NTLM
  • Active Directory, or local window policies that could impact the authentication. N/A

Additional context
N/A

When we authenticate non administrators access user, throwing SEC_E_LOGON_DENIED error

Here below created user as 'shree' and assigned to 'test-group'. This user not assigned 'Administrators' group. During the auth method call throws the below error. Whereas the user assigned to 'Administrators' group working as fine.

How we can auth without 'Administrators' group added?

Capture

Error: AcceptSecurityContext error: SEC_E_LOGON_DENIED
at Object. (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:142:35)
at step (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:33:23)
at Object.next (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:14:53)
at C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:8:71
at new Promise ()
at __awaiter (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:4:12)
at C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:86:31
at C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:180:15
at Layer.handle [as handle_request] (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\express\lib\router\index.js:317:13)
BadRequestError: Error while doing SSO: AcceptSecurityContext error: SEC_E_LOGON_DENIED
at Object. (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:175:54)
at step (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:33:23)
at Object.next (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:14:53)
at C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:8:71
at new Promise ()
at __awaiter (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:4:12)
at C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:86:31
at C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\node-expose-sspi\dist\sso\auth.js:180:15
at Layer.handle [as handle_request] (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\GITHIKASHREE\VertX\OFFLINE-TEMPLATE-ENGINE\window-user\node_modules\express\lib\router\index.js:317:13)

is there any configuration available?

Hi!

First: This is absolut amazing!! And very useful!

Is there any configuration available. For example i don´t need the groups, so the library must/should not asked about them?

Bye, René

sso.authIsReady is undefined

When you follow the example using node 12.16.1, express ^4.17.1 and node-expose-sspi ^0.1.14 the authIsReady function is not defined

basic POST

I am trying to get a successful result from a POST call. With curl, it succeeds. Also GET calls to the same resource succeed.

in.json contains

{
"LocationCode":"NHSC",
"Deliver_to_Code":"WARD_01",
"ItemNo":"015973",
"CountQuantity":"6"
}

using curl:

C:\Users\joe\OneDrive\Desktop>curl -vvvvvvv --negotiate -u Qwantify:Q!xasQw4N!4#2 -H "Content-Type: application/json" [email protected] http://qds-navmhwk03.qixas.internal:7058/AD_BC140CU01/OData/Company('NHS')/Qwantify_Import_Lines?$format=json

successfully results in:

  • Trying 172.30.20.65...
  • TCP_NODELAY set
  • Connected to qds-navmhwk03.qixas.internal (172.30.20.65) port 7058 (#0)

POST /AD_BC140CU01/OData/Company('NHS')/Qwantify_Import_Lines?$format=json HTTP/1.1
Host: qds-navmhwk03.qixas.internal:7058
User-Agent: curl/7.55.1
Accept: /
Content-Type: application/json
Content-Length: 89

  • upload completely sent off: 89 out of 89 bytes
    < HTTP/1.1 401 Unauthorized
    < Content-Length: 0
    < Server: Microsoft-HTTPAPI/2.0
    < WWW-Authenticate: Negotiate
    < Date: Thu, 26 Nov 2020 22:54:55 GMT
    <
  • Connection #0 to host qds-navmhwk03.qixas.internal left intact
  • Issue another request to this URL: 'http://qds-navmhwk03.qixas.internal:7058/AD_BC140CU01/OData/Company('NHS')/Qwantify_Import_Lines?$format=json'
  • Found bundle for host qds-navmhwk03.qixas.internal: 0x251c10c0e20 [can pipeline]
  • Re-using existing connection! (#0) with host qds-navmhwk03.qixas.internal
  • Connected to qds-navmhwk03.qixas.internal (172.30.20.65) port 7058 (#0)
  • Server auth using Negotiate with user 'Qwantify'

POST /AD_BC140CU01/OData/Company('NHS')/Qwantify_Import_Lines?$format=json HTTP/1.1
Host: qds-navmhwk03.qixas.internal:7058
Authorization: Negotiate TlRMTVNTUAABAAAAt4II4gAAAAAAAAAAAAAAAAAAAAAKAGFKAAAADw==
User-Agent: curl/7.55.1
Accept: /
Content-Type: application/json
Content-Length: 89

  • upload completely sent off: 89 out of 89 bytes
    < HTTP/1.1 401 Unauthorized
    < Content-Length: 0
    < Server: Microsoft-HTTPAPI/2.0
    < WWW-Authenticate: Negotiate TlRMTVNTUAACAAAACgAKADgAAAA1goniEe/uEHN0OkAAAAAAAAAAALgAuABCAAAACgBjRQAAAA9RAEkAWABBAFMAAgAKAFEASQBYAEEAUwABABoAUQBEAFMALQBOAEEAVgBNAEgAVwBLADAAMwAEABwAcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAMAOABRAEQAUwAtAE4AQQBWAE0ASABXAEsAMAAzAC4AcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAUAHABxAGkAeABhAHMALgBpAG4AdABlAHIAbgBhAGwABwAIAKZdsyhHxNYBAAAAAA==
    < Date: Thu, 26 Nov 2020 22:54:55 GMT
    <
  • Connection #0 to host qds-navmhwk03.qixas.internal left intact
  • Issue another request to this URL: 'http://qds-navmhwk03.qixas.internal:7058/AD_BC140CU01/OData/Company('NHS')/Qwantify_Import_Lines?$format=json'
  • Found bundle for host qds-navmhwk03.qixas.internal: 0x251c10c0e20 [can pipeline]
  • Re-using existing connection! (#0) with host qds-navmhwk03.qixas.internal
  • Connected to qds-navmhwk03.qixas.internal (172.30.20.65) port 7058 (#0)
  • Server auth using Negotiate with user 'Qwantify'

POST /AD_BC140CU01/OData/Company('NHS')/Qwantify_Import_Lines?$format=json HTTP/1.1
Host: qds-navmhwk03.qixas.internal:7058
Authorization: Negotiate TlRMTVNTUAADAAAAGAAYAIYAAAB+AX4BngAAAAAAAABYAAAAEAAQAFgAAAAeAB4AaAAAABAAEAAcAgAANYKI4goAYUoAAAAPWG4q5cjLo6jgklPzUVl9CFEAdwBhAG4AdABpAGYAeQBEAEUAUwBLAFQATwBQAC0ASwA4AEIAQQBDAEkAUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFyYJUa9TzMpI1QxTSIwEzAQEAAAAAAACmXbMoR8TWARnjOfkIH8UTAAAAAAIACgBRAEkAWABBAFMAAQAaAFEARABTAC0ATgBBAFYATQBIAFcASwAwADMABAAcAHEAaQB4AGEAcwAuAGkAbgB0AGUAcgBuAGEAbAADADgAUQBEAFMALQBOAEEAVgBNAEgAVwBLADAAMwAuAHEAaQB4AGEAcwAuAGkAbgB0AGUAcgBuAGEAbAAFABwAcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAcACACmXbMoR8TWAQYABAACAAAACAAwADAAAAAAAAAAAQAAAAAgAAAsUg5CIZOSJVbd/NreKLGp6n2JVAk2E9UVjeOHmizgqgoAEAAAAAAAAAAAAAAAAAAAAAAACQBCAEgAVABUAFAALwBxAGQAcwAtAG4AYQB2AG0AaAB3AGsAMAAzAC4AcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAAAAAAAAAAA42YkBSLuYBikiB93YhILYg==
User-Agent: curl/7.55.1
Accept: /
Content-Type: application/json
Content-Length: 89

However, when I try to POST with library in node I get a 400:
The code is just a slightly modified version of client-runas.js

const { sso } = require('node-expose-sspi');
const yargs = require('yargs');
const dbg = require('debug');
const debug = dbg('node-expose-sspi:client-runas');

const myArgv = yargs
.usage('$0 [url]', 'Request a url (by default http://localhost:3000)')
.option('url', {
type: 'string',
description: 'Absolute url',
default: 'http://qds-navmhwk03.qixas.internal:7058/AD_BC140CU01/OData/Company(\'NHS\')/Qwantify_Import_Lines?$format=json',
})
.option('target', {
alias: 't',
type: 'string',
description: 'Specify the target name (SPN)',
})
.option('ssp', {
alias: 's',
type: 'string',
description: 'Specify the SSP (Kerberos, NTLM, Negotiate)',
default: 'Negotiate',
})
.option('user', {
alias: 'u',
type: 'string',
description: 'Run as user',
default: 'Qwantify',
})
.option('password', {
alias: 'p',
type: 'string',
description: 'user password',
default: 'Q!xasQw4N!4#2',
})
.option('domain', {
alias: 'd',
type: 'string',
description: 'the windows domain',
default: 'Qixas',
})
.help()
.alias('h', 'help').argv;

async function main(argv) {
debug('argv: ', argv);
const url = argv.url;
const client = new sso.Client();
try {
if (argv.user !== undefined) {
client.setCredentials(argv.domain, argv.user, argv.password);
}
if (argv.target !== undefined) {
client.setTargetName(argv.target);
}
if (argv.ssp !== undefined) {
client.setSSP(argv.ssp);
}

    const headers = {
        "Content-Type": "application/json",
    }

    const data = {
        LocationCode:"NHSC",
        Deliver_to_Code:"WARD_01",
        ItemNo:"015973",
        CountQuantity:"6",
    }

    const init = {
        method: 'POST',
        headers: headers ,
        body: data
    }

    const response = await client.fetch(url, init ) ;
    debug('response: ', response);

    if (response.status >= 400) {
        throw new Error('fetch returned response with error ' + response.status);
    }

    const json = await response.json();

} catch (e) {
    console.error(e);
}

}

main(myArgv);

results:

"C:\Program Files\nodejs\node.exe" C:\Users\joe\projects\qwantify_dbc365\src\client\basic_post.js
node-expose-sspi:client-runas argv: {
_: [],
url: "http://qds-navmhwk03.qixas.internal:7058/AD_BC140CU01/OData/Company('NHS')/Qwantify_Import_Lines?$format=json",
ssp: 'Negotiate',
s: 'Negotiate',
user: 'Qwantify',
u: 'Qwantify',
password: 'Q!xasQw4N!4#2',
p: 'Q!xasQw4N!4#2',
domain: 'Qixas',
d: 'Qixas',
'$0': 'src\client\basic_post.js'
} +0ms
node-expose-sspi:client start response.headers Headers {
[Symbol(map)]: [Object: null prototype] {
'content-length': [ '0' ],
server: [ 'Microsoft-HTTPAPI/2.0' ],
'www-authenticate': [ 'Negotiate' ],
date: [ 'Thu, 26 Nov 2020 23:03:40 GMT' ],
connection: [ 'close' ]
}
} +0ms
node-expose-sspi:client response.status 401 +0ms
node-expose-sspi:client cookieList: {} +0ms
node-expose-sspi:client starting negotiate auth +0ms
node-expose-sspi:client packageInfo: {
fCapabilities: '0x00883bb3',
wVersion: 1,
wRPCID: 9,
cbMaxToken: 48256,
Name: 'Negotiate',
Comment: 'Microsoft Package Negotiator'
} +1ms
node-expose-sspi:client credInput: {
packageName: 'Negotiate',
credentialUse: 'SECPKG_CRED_OUTBOUND',
authData: { domain: 'Qixas', user: 'Qwantify', password: 'Q!xasQw4N!4#2' }
} +0ms
node-expose-sspi:client Client running on a host that is not part of a Microsoft domain +0ms
node-expose-sspi:client targetName: whatever +1ms
node-expose-sspi:client wwwAuthenticateHeader: Negotiate +0ms
node-expose-sspi:client input: {
isFirstCall: true,
credential: '0x0000028cffcce250.0x00000191073a7770',
targetName: 'whatever',
contextReq: [
'ISC_REQ_CONNECTION',
'ISC_REQ_CONFIDENTIALITY',
'ISC_REQ_MUTUAL_AUTH',
'ISC_REQ_REPLAY_DETECT'
],
cbMaxToken: 48256,
targetDataRep: 'SECURITY_NATIVE_DREP'
} +0ms
node-expose-sspi:client clientSecurityContext: {
contextHandle: '0x0000028cff4d1ca0.0x000001910598bd00',
contextAttr: [ 'ISC_RET_INTERMEDIATE_RETURN' ],
SECURITY_STATUS: 'SEC_I_CONTINUE_NEEDED',
SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] }
} +3ms
node-expose-sspi:misc buffer length 40 +0ms
node-expose-sspi:client 0x00000000:4e 54 4c 4d 53 53 50 00 01 00 00 00 b7 82 08 e2 : NTLMSSP.........
node-expose-sspi:client 0x00000016:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
node-expose-sspi:client 0x00000032:0a 00 61 4a 00 00 00 0f : ..aJ....
node-expose-sspi:client +0ms
node-expose-sspi:client debugObject: {
messageType: 'NEGOTIATE_MESSAGE (type 1)',
flags: 'UNICODE OEM NTLMSSP_REQUEST_TARGET SIGN SEAL LM_KEY NTLM ALWAYS_SIGN EXTENDED_SESSIONSECURITY VERSION 128 KEY_EXCH 56',
suppliedDomain: { length: 0, allocated: 0, offset: 0 },
suppliedWorkstation: { length: 0, allocated: 0, offset: 0 },
osVersionStructure: {
majorVersion: 10,
minorVersion: 0,
buildNumber: 19041,
unknown: 15
},
suppliedDomainData: '',
suppliedWorkstationData: ''
} +1ms
node-expose-sspi:client requestInit.headers {
'Content-Type': 'application/json',
Authorization: 'Negotiate TlRMTVNTUAABAAAAt4II4gAAAAAAAAAAAAAAAAAAAAAKAGFKAAAADw=='
} +1ms
node-expose-sspi:client response.status 401 +81ms
node-expose-sspi:client response.headers Headers {
[Symbol(map)]: [Object: null prototype] {
'content-length': [ '0' ],
server: [ 'Microsoft-HTTPAPI/2.0' ],
'www-authenticate': [
'Negotiate TlRMTVNTUAACAAAACgAKADgAAAA1goniktNOEHUoMVwAAAAAAAAAALgAuABCAAAACgBjRQAAAA9RAEkAWABBAFMAAgAKAFEASQBYAEEAUwABABoAUQBEAFMALQBOAEEAVgBNAEgAVwBLADAAMwAEABwAcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAMAOABRAEQAUwAtAE4AQQBWAE0ASABXAEsAMAAzAC4AcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAUAHABxAGkAeABhAHMALgBpAG4AdABlAHIAbgBhAGwABwAIAKaNUmFIxNYBAAAAAA=='
],
date: [ 'Thu, 26 Nov 2020 23:03:40 GMT' ]
}
} +0ms
node-expose-sspi:client cookieList: {} +90ms
node-expose-sspi:client wwwAuthenticateHeader: Negotiate TlRMTVNTUAACAAAACgAKADgAAAA1goniktNOEHUoMVwAAAAAAAAAALgAuABCAAAACgBjRQAAAA9RAEkAWABBAFMAAgAKAFEASQBYAEEAUwABABoAUQBEAFMALQBOAEEAVgBNAEgAVwBLADAAMwAEABwAcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAMAOABRAEQAUwAtAE4AQQBWAE0ASABXAEsAMAAzAC4AcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAUAHABxAGkAeABhAHMALgBpAG4AdABlAHIAbgBhAGwABwAIAKaNUmFIxNYBAAAAAA== +1ms
node-expose-sspi:client bufferStr: TlRMTVNTUAACAAAACgAKADgAAAA1goniktNOEHUoMVwAAAAAAAAAALgAuABCAAAACgBjRQAAAA9RAEkAWABBAFMAAgAKAFEASQBYAEEAUwABABoAUQBEAFMALQBOAEEAVgBNAEgAVwBLADAAMwAEABwAcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAMAOABRAEQAUwAtAE4AQQBWAE0ASABXAEsAMAAzAC4AcQBpAHgAYQBzAC4AaQBuAHQAZQByAG4AYQBsAAUAHABxAGkAeABhAHMALgBpAG4AdABlAHIAbgBhAGwABwAIAKaNUmFIxNYBAAAAAA== +0ms
node-expose-sspi:client responseToken: {
messageType: 'CHALLENGE_MESSAGE (type 2)',
targetNameSecBuf: { length: 10, allocated: 10, offset: 56 },
flags: 'UNICODE NTLMSSP_REQUEST_TARGET SIGN SEAL NTLM ALWAYS_SIGN NTLMSSP_TARGET_TYPE_DOMAIN EXTENDED_SESSIONSECURITY TARGET_INFO VERSION 128 KEY_EXCH 56',
challenge: '92d34e107528315c',
targetNameData: 'QIXAS',
context: '0000000000000000',
targetInfoSecBuf: { length: 184, allocated: 184, offset: 66 },
targetInfoData: [
{ type: 2, length: 10, content: 'QIXAS' },
{ type: 1, length: 26, content: 'QDS-NAVMHWK03' },
{ type: 4, length: 28, content: 'qixas.internal' },
{ type: 3, length: 56, content: 'QDS-NAVMHWK03.qixas.internal' },
{ type: 5, length: 28, content: 'qixas.internal' },
{ type: 7, length: 8, content: '2020-11-26T23:03:40.349Z' },
{ type: 0, length: 0, content: '' }
],
osVersionStructure: {
majorVersion: 10,
minorVersion: 0,
buildNumber: 17763,
unknown: 15
}
} +0ms
node-expose-sspi:client input: {
isFirstCall: false,
credential: '0x0000028cffcce250.0x00000191073a7770',
targetName: 'whatever',
contextReq: [
'ISC_REQ_CONNECTION',
'ISC_REQ_CONFIDENTIALITY',
'ISC_REQ_MUTUAL_AUTH',
'ISC_REQ_REPLAY_DETECT'
],
cbMaxToken: 48256,
targetDataRep: 'SECURITY_NATIVE_DREP',
SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
contextHandle: '0x0000028cff4d1ca0.0x000001910598bd00'
} +1ms
node-expose-sspi:client clientSecurityContext: {
contextHandle: '0x0000028cff4d1ca0.0x000001910598bd00',
contextAttr: [
'ISC_RET_MUTUAL_AUTH',
'ISC_RET_REPLAY_DETECT',
'ISC_RET_SEQUENCE_DETECT',
'ISC_RET_CONFIDENTIALITY',
'ISC_RET_INTEGRITY'
],
SECURITY_STATUS: 'SEC_E_OK',
SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] }
} +1ms
node-expose-sspi:misc buffer length 516 +86ms
node-expose-sspi:client 0x00000000:4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00 : NTLMSSP.........
node-expose-sspi:client 0x00000016:90 00 00 00 4c 01 4c 01 a8 00 00 00 0a 00 0a 00 : ....L.L.........
node-expose-sspi:client 0x00000032:58 00 00 00 10 00 10 00 62 00 00 00 1e 00 1e 00 : X.......b.......
node-expose-sspi:client 0x00000048:72 00 00 00 10 00 10 00 f4 01 00 00 35 82 88 e2 : ............5...
node-expose-sspi:client 0x00000064:0a 00 61 4a 00 00 00 0f 29 02 12 67 6c 5d d0 88 : ..aJ.......gl...
node-expose-sspi:client 0x00000080:f3 3e 86 d2 a1 ff 2e ea 51 00 69 00 78 00 61 00 : ........Q.i...a.
node-expose-sspi:client 0x00000096:73 00 51 00 77 00 61 00 6e 00 74 00 69 00 66 00 : ..Q...a.n...i.f.
node-expose-sspi:client 0x00000112:79 00 44 00 45 00 53 00 4b 00 54 00 4f 00 50 00 : ..D.E.S.K.T.O.P.
node-expose-sspi:client 0x00000128:2d 00 4b 00 38 00 42 00 41 00 43 00 49 00 51 00 : ..K.8.B.A.C.I.Q.
node-expose-sspi:client 0x00000144:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
node-expose-sspi:client 0x00000160:00 00 00 00 00 00 00 00 02 33 f5 42 c1 47 c0 3d : .........3.B.GÀ.
node-expose-sspi:client 0x00000176:25 18 64 0a 04 df cf 7d 01 01 00 00 00 00 00 00 : ..d.............
node-expose-sspi:client 0x00000192:a6 8d 52 61 48 c4 d6 01 88 c2 c6 6b 17 b0 d9 56 : ..RaH......k...V
node-expose-sspi:client 0x00000208:00 00 00 00 02 00 0a 00 51 00 49 00 58 00 41 00 : ........Q.I.X.A.
node-expose-sspi:client 0x00000224:53 00 01 00 1a 00 51 00 44 00 53 00 2d 00 4e 00 : S.....Q.D.S...N.
node-expose-sspi:client 0x00000240:41 00 56 00 4d 00 48 00 57 00 4b 00 30 00 33 00 : A.V.M.H.W.K.0.3.
node-expose-sspi:client 0x00000256:04 00 1c 00 71 00 69 00 78 00 61 00 73 00 2e 00 : ......i...a.....
node-expose-sspi:client 0x00000272:69 00 6e 00 74 00 65 00 72 00 6e 00 61 00 6c 00 : i.n...e...n.a.l.
node-expose-sspi:client 0x00000288:03 00 38 00 51 00 44 00 53 00 2d 00 4e 00 41 00 : ..8.Q.D.S...N.A.
node-expose-sspi:client 0x00000304:56 00 4d 00 48 00 57 00 4b 00 30 00 33 00 2e 00 : V.M.H.W.K.0.3...
node-expose-sspi:client 0x00000320:71 00 69 00 78 00 61 00 73 00 2e 00 69 00 6e 00 : ..i...a.....i.n.
node-expose-sspi:client 0x00000336:74 00 65 00 72 00 6e 00 61 00 6c 00 05 00 1c 00 : ..e...n.a.l.....
node-expose-sspi:client 0x00000352:71 00 69 00 78 00 61 00 73 00 2e 00 69 00 6e 00 : ..i...a.....i.n.
node-expose-sspi:client 0x00000368:74 00 65 00 72 00 6e 00 61 00 6c 00 07 00 08 00 : ..e...n.a.l.....
node-expose-sspi:client 0x00000384:a6 8d 52 61 48 c4 d6 01 06 00 04 00 02 00 00 00 : ..RaH...........
node-expose-sspi:client 0x00000400:08 00 30 00 30 00 00 00 00 00 00 00 01 00 00 00 : ..0.0...........
node-expose-sspi:client 0x00000416:00 20 00 00 2c 52 0e 42 21 93 92 25 56 dd fc da : . ...R.B....VÝ..
node-expose-sspi:client 0x00000432:de 28 b1 a9 ea 7d 89 54 09 36 13 d5 15 8d e3 87 : Þ......T.6......
node-expose-sspi:client 0x00000448:9a 2c e0 aa 0a 00 10 00 00 00 00 00 00 00 00 00 : ................
node-expose-sspi:client 0x00000464:00 00 00 00 00 00 00 00 09 00 10 00 77 00 68 00 : ..............h.
node-expose-sspi:client 0x00000480:61 00 74 00 65 00 76 00 65 00 72 00 00 00 00 00 : a...e...e.......
node-expose-sspi:client 0x00000496:00 00 00 00 2e 96 11 82 bc 29 a5 66 eb 63 3e 8e : ........¼..f.c..
node-expose-sspi:client 0x00000512:1c 1b 1d e9 : ....
node-expose-sspi:client +0ms
node-expose-sspi:client debugObject: {
messageType: 'NEGOTIATE_MESSAGE (type 3)',
version: 3,
lmResponse: { length: 24, allocated: 24, offset: 144 },
ntlmResponse: { length: 332, allocated: 332, offset: 168 },
targetName: { length: 10, allocated: 10, offset: 88 },
userName: { length: 16, allocated: 16, offset: 98 },
workstationName: { length: 30, allocated: 30, offset: 114 },
lmResponseData: { hex: '000000000000000000000000000000000000000000000000' },
ntlmResponseData: {
hex: '0233f542c147c03d2518640a04dfcf7d0101000000000000a68d526148c4d60188c2c66b17b0d9560000000002000a005100490058004100530001001a005100440053002d004e00410056004d00480057004b003000330004001c00710069007800610073002e0069006e007400650072006e0061006c00030038005100440053002d004e00410056004d00480057004b00300033002e00710069007800610073002e0069006e007400650072006e0061006c0005001c00710069007800610073002e0069006e007400650072006e0061006c0007000800a68d526148c4d601060004000200000008003000300000000000000001000000002000002c520e422193922556ddfcdade28b1a9ea7d8954093613d5158de3879a2ce0aa0a0010000000000000000000000000000000000009001000770068006100740065007600650072000000000000000000'
},
targetNameData: 'Qixas',
userNameData: 'Qwantify',
workstationNameData: 'DESKTOP-K8BACIQ',
sessionKey: { length: 16, allocated: 16, offset: 500 },
flags: 'UNICODE NTLMSSP_REQUEST_TARGET SIGN SEAL NTLM ALWAYS_SIGN EXTENDED_SESSIONSECURITY TARGET_INFO VERSION 128 KEY_EXCH 56',
osVersionStructure: {
majorVersion: 10,
minorVersion: 0,
buildNumber: 19041,
unknown: 15
}
} +1ms
node-expose-sspi:client requestInit.headers {
'Content-Type': 'application/json',
Authorization: 'Negotiate TlRMTVNTUAADAAAAGAAYAJAAAABMAUwBqAAAAAoACgBYAAAAEAAQAGIAAAAeAB4AcgAAABAAEAD0AQAANYKI4goAYUoAAAAPKQISZ2xd0IjzPobSof8u6lEAaQB4AGEAcwBRAHcAYQBuAHQAaQBmAHkARABFAFMASwBUAE8AUAAtAEsAOABCAEEAQwBJAFEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjP1QsFHwD0lGGQKBN/PfQEBAAAAAAAApo1SYUjE1gGIwsZrF7DZVgAAAAACAAoAUQBJAFgAQQBTAAEAGgBRAEQAUwAtAE4AQQBWAE0ASABXAEsAMAAzAAQAHABxAGkAeABhAHMALgBpAG4AdABlAHIAbgBhAGwAAwA4AFEARABTAC0ATgBBAFYATQBIAFcASwAwADMALgBxAGkAeABhAHMALgBpAG4AdABlAHIAbgBhAGwABQAcAHEAaQB4AGEAcwAuAGkAbgB0AGUAcgBuAGEAbAAHAAgApo1SYUjE1gEGAAQAAgAAAAgAMAAwAAAAAAAAAAEAAAAAIAAALFIOQiGTkiVW3fza3iixqep9iVQJNhPVFY3jh5os4KoKABAAAAAAAAAAAAAAAAAAAAAAAAkAEAB3AGgAYQB0AGUAdgBlAHIAAAAAAAAAAAAulhGCvCmlZutjPo4cGx3p'
} +1ms
node-expose-sspi:client response.status 400 +46ms
node-expose-sspi:client response.headers Headers {
[Symbol(map)]: [Object: null prototype] {
'content-length': [ '113' ],
'content-type': [
'application/json;odata=minimalmetadata;streaming=true;charset=utf-8'
],
server: [ 'Microsoft-HTTPAPI/2.0' ],
'x-content-type-options': [ 'nosniff' ],
dataserviceversion: [ '3.0;' ],
date: [ 'Thu, 26 Nov 2020 23:03:40 GMT' ]
}
} +1ms
node-expose-sspi:client cookieList: {} +52ms
node-expose-sspi:client handleAuth: end +1ms
node-expose-sspi:client-runas response: Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kTransformState)]: [Object]
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: 'http://qds-navmhwk03.qixas.internal:7058/AD_BC140CU01/OData/Company(%27NHS%27)/Qwantify_Import_Lines?$format=json',
status: 400,
statusText: 'Bad Request',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
} +222ms
Error: fetch returned response with error 400
at main (C:\Users\joe\projects\qwantify_dbc365\src\client\basic_post.js:86:19)
at processTicksAndRejections (internal/process/task_queues.js:93:5)

Process finished with exit code 0

I can't figure out what's going wrong. It's authenticating correctly I"m pretty sure, but I don't know why I"m getting a 400?

Question: Cannot work with useActiveDirectory=true.

Hi there...

I have some questions:

When i put the sample-code on the server it will only run then useActiveDirectory=false and cookies=true.
How can i check on the server that there is a reachable Active Directory? And will the combination of useActiveDirectory=true and cookies=true never run?

I am not familar with the complete technic behind the auth...

best wishes...
rené...

Correct authentication fails after bad authentication

I am testing both the client and server feature along with the setCredentials function to test logins with good and bad credentials. If I have good credentials it works as expected. If I have bad credentials, it fails as expected. But if I put in good credentials after bad credentials I get adding to input a serverContextHandle (not first exchange) right after the NTLM_NEGOTIATE_01 and then it hangs.

It seems to me that it isn't re-initializing properly after submitting bad credentials.

Note: I have set useCookies: false and useGroups: false

BadRequestError Issues

As I am implementing node-expose-sspi and running a script on Windows OS (64-bit) with nodejs (32-bit), I am encountering the following errors:

Please note that whitelisting has not been applied.

This error occurs after I manually insert my valid credentials into the pop-up:

  1. "BadRequestError: Error while doing SSO: AcceptSecurityContext error: SEC_E_LOGON_DENIED"

This error occurs where I attempt multiple requests to the domain:
2. "BadRequestError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090310) The message supplied for verification is out of sequence."

Issue with SSO: AcceptSecurityContext: SECURITY_STATUS incorrect only with specific windows machine.

Describe the bug

Actual use case issue.

I have integrated node-expose-sspi into my application, it worked on my dev windows 10 machine, but after i move my code to another windows 10 machine, it did not work, and start crashing on the application, when the request passes through sso.auth() middleware.

After isolating the middleware, and debug the auth(), I found myself with the following error
UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid

Basic debugging with simple sso test example
Followed instructions on https://github.com/jlguenego/node-expose-sspi/blob/master/doc/use-case/errors.md for basic debugging
Behaviors observed:

  • type localhost:3000, application crash with [nodemon] app crashed - waiting for file changes before starting...
  • type 127.0.0.1:3000, provide correct credential - NTLM authentication works, and sso result is returned in json.
  • type 127.0.0.1:3000, provide incorrect credential - error is generated in console

UnauthorizedError: SEC_E_LOGON_DENIED. (incorrect login/password, or account disabled, or locked, etc.). Protocol Message = NTLM_AUTHENTICATE_03. at Object.<anonymous> (D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\node-expose-sspi\dist\sso\auth.js:168:62) at step (D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\node-expose-sspi\dist\sso\auth.js:33:23) at Object.next (D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\node-expose-sspi\dist\sso\auth.js:14:53) at D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\node-expose-sspi\dist\sso\auth.js:8:71 at new Promise (<anonymous>) at __awaiter (D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\node-expose-sspi\dist\sso\auth.js:4:12) at D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\node-expose-sspi\dist\sso\auth.js:103:31 at D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\node-expose-sspi\dist\sso\auth.js:225:15 at Layer.handle [as handle_request] (D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (D:\git.repo\node-expose-sspi\examples\express-simple\node_modules\express\lib\router\index.js:317:13)

To Reproduce

To reproduce, the issue is system specific without clear knowledge of what configuration is missing.
Can the observation in the basic debugging above provides a good idea what other test i could try out next?

Trace
Mind to provide some details on what to provide?
I notice that is exposure of hostname and credential details in the stack trace, which i hope i can avoid providing.

Expected behavior
According to the working version of the code running on the previous dev machine, the sso.auth() should function correctly without throwing any error. I expect the request.sso to provide the most minimum details available without AD.

Environment version:

  • OS: Windows 10
  • Browser Chrome
  • Version Version 85.0.4183.121 (Official Build) (64-bit)

Please indicates also:

  • Are you on a Windows domain ? NO
  • Can you reach the domain controller ? NO
  • Do your session have admin privileges ? NO
  • Which authentication protocol ? NO
  • Active Directory, or local window policies that could impact the authentication. No AD, how can i provide the policy details?

Additional context
Add any other context about the problem here.

UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect

Hi,

I'm trying to use node-expose-sspi in production for Kerberos authentication. Everything works fine on my development setup, but when I tried it on production, I get the error trace below:

7|index  | 2020-11-26T11:10:16.743Z node-expose-sspi:schManager initCookie
7|index  | 2020-11-26T11:10:16.743Z node-expose-sspi:auth cookieToken:  NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.743Z node-expose-sspi:auth no authorization key in header
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:schManager initCookie
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth cookieToken:  NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:misc buffer length 1710
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth messageType:  Kerberos_1
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:misc buffer length 1710
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth <Long chunk of hexadecimals>
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:schManager wait for release with cookie NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth schManager waitForReleased finished.
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:schManager cookieToken:  NEGOTIATE_7978678688
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth set cookie bug management
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:auth input just before calling AcceptSecurityContext {
7|index  |   credential: '<hexadecimal string>.<hexadecimal string>',
7|index  |   SecBufferDesc: { ulVersion: 0, buffers: [ [ArrayBuffer] ] },
7|index  |   contextHandle: '0x000002a225ebf6b0.0x0000019cf4b62f60'
7|index  | }
7|index  | Error: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid
7|index  |     at F:\Backend\node_modules\node-expose-sspi\dist\sso\auth.js:116:58
7|index  | 2020-11-26T11:10:16.775Z node-expose-sspi:adConnection openADConnection: counter:  1
7|index  | 2020-11-26T11:10:16.790Z node-expose-sspi:adConnection closeADConnection: counter:  0
7|index  | statusInfo:  {
7|index  |   adminPrivileges: false,
7|index  |   isOnDomain: true,
7|index  |   domain: 'MYDOMAIN',
7|index  |   isActiveDirectoryReachable: true
7|index  | }
7|index  | messageType:  Kerberos_1
7|index  | UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid
7|index  |     at F:\Backend\node_modules\node-expose-sspi\dist\sso\auth.js:177:43

Additional context

  • Browser: Internet Explorer 11
  • node-expose-sspi (version 0.1.51) is used with ExpressJS (runs on PM2)
  • Client uses ReactJS and runs on IIS 10
  • IIS reverse proxy is used for ExpressJS

Hope you can advise on how I can solve this problem. Thanks.

express-jwt must be removed.

01 July 2020 : received deprecation notice and security alert on express-jwt.

Because express-jwt is not used anymore, it is decided to remove it from the project.

Compatibility with npm pkg

WARNING: PLEASE READ THE DOC FOR DEBUGGING YOURSELF.

Describe the bug

Not exactly a bug, but a nice to have.

When attempting to use the fairly popular npm pkg tool to pack a project into an exe, the node-expose-sspi.node binary is not included in the package.

The reason is likely that you have in api.js

const filename = ./arch/${process.arch}/node-expose-sspi.node; module.exports = require(filename);

had you put it in one line like

module.exports = require( ./arch/${process.arch}/node-expose-sspi.node);`

I think that the pkg parser would have picked it up and included it.

However, it may also be useful to approach it like npm systray which allows a different directory for the binary to be specified.

To Reproduce

Please provide the minimum of code to reproduce the issue.
You can provide the code directly in the issue, or through a github project that you make for proving the defect.

Indicate the step to reproduce if necessary, like:

  1. npm install pkg -g
  2. pkg [something using expose sspi].js
  3. [something using expose sspi].exe
  4. See error

Trace
pkg/prelude/bootstrap.js:1244
throw error;
^

Error: Cannot find module './arch/x64/node-expose-sspi.node'
Require stack:

  • C:\snapshot\sspi-authenticate\node_modules\node-expose-sspi\lib\api.js
  • C:\snapshot\sspi-authenticate\node_modules\node-expose-sspi\dist\index.js
  • C:\snapshot\sspi-authenticate\SSPI-authentication-server.js
  1. If you want to compile the package/file into executable, please pay attention
    to compilation warnings and specify a literal in 'require' call. 2) If you don'
    t want to compile the package/file into executable and want to 'require' it from
    filesystem (likely plugin), specify an absolute path in 'require' call using pr
    ocess.cwd() or process.execPath.
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:964:15)
    at Function.Module._resolveFilename (pkg/prelude/bootstrap.js:1346:46)
    at Function.Module._load (internal/modules/cjs/loader.js:840:27)
    at Module.require (internal/modules/cjs/loader.js:1024:19)
    at Module.require (pkg/prelude/bootstrap.js:1225:31)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object. (C:\snapshot\sspi-authenticate\node_modules\node-expos
    e-sspi\lib\api.js:2:18)
    at Module._compile (pkg/prelude/bootstrap.js:1320:22)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1156:10)
    at Module.load (internal/modules/cjs/loader.js:984:32) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
    'C:\snapshot\sspi-authenticate\node_modules\node-expose-sspi\lib\api.j
    s',
    'C:\snapshot\sspi-authenticate\node_modules\node-expose-sspi\dist\inde
    x.js',
    'C:\snapshot\sspi-authenticate\SSPI-authentication-server.js'
    ],
    pkg: true
    }
    Expected behavior

No errors when running packaged executable.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context

See warning text about using a string literal for require.

getUsers LDAP Filter

Would it be possible to add an optional ldapFilter argument to getUsers as is the case with getUser?

Happy to raise a PR if needed.

Missing adUser property in the user object

Hi first of all thank you for this module, the documentation and examples has helped me a lot.

Describe the bug
The issue I have is when using the sso.auth() middleware, the req.sso object doesn't contain the adUser object anymore. We plan to use the userPrincipalName property to link it with application user. I notice this object was there previously by running the react example, but in the latest versions it is not present
Is this removal was intentional and if so is there a possibility to get access to this object again?

To Reproduce

Run the react example from https://github.com/jlguenego/react-sso-example, or install the version 0.1.3. This would have the adUser property. While running one of the latest version (0.1.4x) this property is not there anymore.

The code for the middleware :

  app.get('/api/auth/authenticated', sso.auth(), async (req, res) => {
    if (!req.sso) {
      return res.status(401).end();
    }
    return res.json({
      sso: req.sso
    });
  });

Environment version:

  • OS: Windows 10 Pro version 1903 x64
  • Browser version: Chrome / Edge
  • Node version and architecture: 12.18.2 64bits

Please indicates also:

  • Are you on a Windows domain ? yes
  • Can you reach the domain controller ? yes
  • Do your session have admin privileges ? no
  • Which authentication protocol ? NTLM for now, Kerberos later
  • Active Directory, or local window policies that could impact the authentication.

AcceptSecurityContext: SECURITY_STATUS incorrect

Hi,

I am using the package and when I call the sso.auth() function for the second time I am seeing this error. I have exposed an endpoint for login. When I browser from chrome (http://localhost:5000/api/login) or the first time, I am able to see all the sso details. When I browse it for the second time I am receiving the below error. Could you please guide me where I am doing wrong?

//Login end point
app.get('/api/login', sso.auth(), (req, res, next) => {
req.session.sso = req.sso;
res.send(req.sso);
});

Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid
401
UnauthorizedError: Error while doing SSO: AcceptSecurityContext: SECURITY_STATUS incorrect (<0): (error code: 0x80090308) The token supplied to the function is invalid

at Object.<anonymous> (D:\Sources\api\src\node_modules\node-expose-sspi\dist\sso\auth.js:190:54)
at step (D:\Sources\api\src\node_modules\node-expose-sspi\dist\sso\auth.js:33:23)
at Object.next (D:\Sources\api\src\node_modules\node-expose-sspi\dist\sso\auth.js:14:53)
at D:\Sources\api\src\node_modules\node-expose-sspi\dist\sso\auth.js:8:71
at new Promise (<anonymous>)
at __awaiter (D:\Sources\api\src\node_modules\node-expose-sspi\dist\sso\auth.js:4:12)
at D:\Sources\api\src\node_modules\node-expose-sspi\dist\sso\auth.js:88:31
at D:\Sources\api\src\node_modules\node-expose-sspi\dist\sso\auth.js:195:15
at Layer.handle [as handle_request] (D:\Sources\api\src\node_modules\express\lib\router\layer.js:95:5)
at next (D:\Sources\api\src\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (D:\Sources\api\src\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (D:\Sources\api\src\node_modules\express\lib\router\layer.js:95:5)
at D:\Sources\api\src\node_modules\express\lib\router\index.js:281:22
at Function.process_params (D:\Sources\api\src\node_modules\express\lib\router\index.js:335:12)
at next (D:\Sources\api\src\node_modules\express\lib\router\index.js:275:10)
at D:\Sources\api\src\app.js:79:13
at Layer.handle [as handle_request] (D:\Sources\api\src\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (D:\Sources\api\src\node_modules\express\lib\router\index.js:317:13)
at D:\Sources\api\src\node_modules\express\lib\router\index.js:284:7
at Function.process_params (D:\Sources\api\src\node_modules\express\lib\router\index.js:335:12)
at next (D:\Sources\api\src\node_modules\express\lib\router\index.js:275:10)
at D:\Sources\api\src\app.js:66:9

sso http client side

Is is possible to do SSO with an http client from a workstation on the same domain as the IIS ( in my case business central through ODATA ) server? Or is that silly?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.