Azure / iisnode

Hosting node.js applications in IIS on Windows
Other
667 stars 101 forks source link

Unable to authenticate using node-sspi and IIS #95

Closed mlaposta closed 4 years ago

mlaposta commented 4 years ago

This seems to have been an issue for quite a while, yet I have not been able to figure out how to fix this.

My setup:

If I run my node app using node-sspi to authenticate, run from the command line, the authentication works perfectly as expected. As soon as I try to run the app from IIS however, the user credentials pop-up always pops up in the browser, but no matter what is entered will never authenticate.

This has been mentioned in other threads, including #https://github.com/tjanczuk/iisnode/issues/658 on tjanczuk's github, but no solution that I can see. I've been trying for weeks to get this working, including the solutions mentioned in this stackoverflow thread but nothing seems to resolve this issue.

It seems IIS is prompting for credentials when the static files are requested via express.static, but I'd assume other scenarios produce the same 401 issues.

Is there any fix for this?

mlaposta commented 4 years ago

Think I may have found the solution to the issue I was having, so adding my solution in case anyone else has the same issue(s).

By default in IIS, "Anonymous Authentication" is enabled, and "ASP.NET Impersonation" and "Windows Authentication" are disabled. In the nodeSSPI object, by default, offerBasic (basic auth) and offerSSPI (not sure what that is - possibly the same as "Windows Authentication in IIS") are both enabled. Well it seems the offerSSPI may have been causing issues with IIS, as disabling it seems to have resolved the issue, and I can now authenticate. As noted in my original post, running from the command line worked fine previously, so something between nodeSSPI and IIS/IISNode was conflicting.

Anyway, hopefully this will help anyone else having the same issue.

mmogannam commented 4 years ago

@mlaposta Any chance you can post an example and a screenshot of your IIS Auth settings / code that works. I am trying to do the exact same thing for a new project and I can't authenticate the window just keeps repeating asking for username and password. I am working off the example here: https://www.npmjs.com/package/node-sspi

My settings look like this:

app.use(function (req, res, next) { var nodeSSPI = require('node-sspi') var nodeSSPIObj = new nodeSSPI({ retrieveGroups: false, offerBasic: false, offerSSPI: false }) nodeSSPIObj.authenticate(req, res, function(err){ res.finished || next() }) })

I ONLY have Windows Authentication enabled on IIS.

Any Thoughts?

mlaposta commented 4 years ago

@mlaposta Any chance you can post an example and a screenshot of your IIS Auth settings / code that works. I am trying to do the exact same thing for a new project and I can't authenticate the window just keeps repeating asking for username and password. I am working off the example here: https://www.npmjs.com/package/node-sspi

My settings look like this:

app.use(function (req, res, next) { var nodeSSPI = require('node-sspi') var nodeSSPIObj = new nodeSSPI({ retrieveGroups: false, offerBasic: false, offerSSPI: false }) nodeSSPIObj.authenticate(req, res, function(err){ res.finished || next() }) })

I ONLY have Windows Authentication enabled on IIS.

Any Thoughts?

So first off, in the nodeSSPIObj, you are disabling both authentications ... you would need at least one enabled.

What I did was set offerBasic to true and offerSSPI to false, and in IIS, keep Windows Authentication disabled, and Anonymous Authentication enabled. This, for me at least, allowed Node (via nodeSSPI) to handle the authent correctly.

When you enable Windows Authentication in IIS, IIS takes over the authentication flow. So technically, with only IIS and IISNode you could handle all of the authentication without the need for nodeSSPI ... however that setup would lack some customization abilities. So with nodeSSPI, my theory is that when you set offerSSPI to true, for some reason IIS blocks it, regardless if "Windows Authentication" is enabled or not in IIS. And that's why the credentials pop-up never accepts any credentials.

To recap, what worked for me was:

var nodeSSPIObj = new nodeSSPI({    // setup the SSPI object
    authoritative: false,                          // make sure we handle all auth cases
    offerBasic: true,                               // offer basic auth
    offerSSPI: false,                               // but disable SSPI auth as IIS seems to block it
    retrieveGroups: true                       // retrieve a user's DLs
});

nodeSSPIObj.authenticate(req, res, function(err) {
    res.finished || next();
});

And in IIS, "Anonymous Authentication" enabled, "Windows Authentication" disabled.

Hope that helps!