jlguenego / node-expose-sspi

Expose Microsoft Windows SSPI to Node for SSO authentication.
ISC License
128 stars 19 forks source link

attempting to connecting in Edge (chromium) - repeatedly prompted for login #149

Closed jg76379 closed 2 years ago

jg76379 commented 2 years ago

Describe the bug

I have tried this with both Node 12.22.12 and 16.15.0.

Express application using node-expose-sspi v0.1.59 is on Machine A, we will call my local machine Machine B. Both are on corporate network.

When connecting in Edge (chromium v101.0.1210.53), from Machine B, it repeatedly prompts for login. No matter how many times i enter my credentials it just keeps prompting. In chrome it works fine, it does not even prompt for credentials.

If I login to Machine A and connect, it works fine in both Edge and Chrome.

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.

I am using the "express-simple" sample for testing.

Indicate the step to reproduce if necessary, like:

  1. Run example code on machine-b
  2. One machine-a open edge and navigate to http://machine-b:3000
  3. When prompted for login enter windows credentials
  4. Prompt appears again...

Trace Do not hesitate to setup env variable DEBUG=node-expose-sspi:*. Then run your project and provide the trace to get a maximum of info.

When i set the DEBUG env variable, instead of getting the login prompt i get the following error:

UnauthorizedError: Error while doing SSO: Cannot read property 'value' of undefined
    at C:\applications\sspi-test\node_modules\node-expose-sspi\dist\sso\auth.js:188:43
    at C:\applications\sspi-test\node_modules\node-expose-sspi\dist\sso\auth.js:190:11
    at Layer.handle [as handle_request] (C:\applications\sspi-test\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\applications\sspi-test\node_modules\express\lib\router\index.js:328:13)
    at C:\applications\sspi-test\node_modules\express\lib\router\index.js:286:9
    at Function.process_params (C:\applications\sspi-test\node_modules\express\lib\router\index.js:346:12)
    at next (C:\applications\sspi-test\node_modules\express\lib\router\index.js:280:10)
    at expressInit (C:\applications\sspi-test\node_modules\express\lib\middleware\init.js:40:5)
    at Layer.handle [as handle_request] (C:\applications\sspi-test\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\applications\sspi-test\node_modules\express\lib\router\index.js:328:13)

Expected behavior

I should be able to authenticate in Edge from Machine B.

Environment version:

Machine A (server)

Machine B (client)

Please indicates also:

Additional context

Previously I was using the node-sspi package, which worked fine in Node v12.x; however it did not work in Node 14.x or 16.x which is why I am investigating moving to node-expose-sspi.

jg76379 commented 2 years ago

From looking at the output more after setting DEBUG=node-expose-sspi:*, it seems that in Chrome from Machine B. and Chrome or Edge from machine A it is using NTLM.

But when connecting from Machine B it is trying to use Kerberos and failing.

If I force NTLM with sso.auth({forceNTLM: true}), then it does work from Edge on Machine B.

So it looks like this is actually just a Kerberos issue with my setup, I will follow the instructions here to try to fix this.

(Yes I figured this out while writing the issue but I thought i would post anyway in case someone else runs across the same issue).

jdjuan commented 2 years ago

Using sso.auth({forceNTLM: true}) solved my issue @jg76379! Thank you! ❤️

I'd have expected NTLM to always prompt me for credentials, but it seems like it doesn't do it when your server is defined as an intranet site. That's great because the only reason I wanted to use Kerberos in the first place was to avoid the prompt.

More information on the bug

I debugged my problem with Kerberos. I found out that the BERDecoder used by the node-expose-sspi was struggling to decode the Kerberos ticket.

There was an OCTET_STRING inside my Kerberos ticket buffer that was not properly decoded by the library, therefore the library couldn't find the principalName, or the realm, leading to Cannot read property 'value' of undefined).

When I passed the same Buffer object to an external online decoder, the ticket was properly decoded.

I can't be sure what's exactly going on but here are some possibilities:

  1. My Kerberos is poorly set up and the library is doing its job well
  2. My Kerberos is properly set up but the library has a decoding bug
  3. My Kerberos version is not supported by the library

I did find a comment on the code that said: // 8.7.1 The encoding of an octetstring value shall be either primitive or constructed at the option of the sender.. So maybe my Kerberos ticket (more specifically the octec_string) was poorly constructed.