简体   繁体   中英

IIS Node and Windows Authentication: IIS-Website Keeps prompting for Credentials

I have an IIS Website that runs on localhost:3000 using NodeJS, Express, passport and passport-windowsauth .

When I try to access the URL, it keeps prompting for user credentials - even if I type in the correct credentials. It simply pops up again. If I choose "Cancel", I obviously get the "Unauthorized". Struggling with this error since 3 full days and think about just giving up. I tried nearly every possible solution I could find, with no success.

And what's strange: This error only occurs on Windows-VM (Virtualbox). On a normal Windows-OS it works like a charm, with the exact same code and same IIS settings. This is driving me crazy.

What I tried:

  • granting Full Access for IUSR / IUSRS group, put NTLM first, enabled Kernel Mode Authentication and set Extended Protection as "Accept" (suggested here )
  • change Application Pool Identity to Local Service , Local System or Managed System
  • added localhost to "Trusted Sites" in Internet Options (even though that felt strange), as suggested here
  • tried enabling Anonymus Authentication with IUSR
  • did security loopback check (suggested here and here )
  • Rebooting after every action I did
  • did iisreset after every action I did
  • checking IIS Node in Handler Mappings
  • adding localhost manually to "Hosts"-file
  • overrideModeDefault = Allow for Windows Authentication (and Anonymus Authentication as well) in applicationHost.config

Also, I have no custom error pages that could be related to the problem.

server.js :

const express = require('express');
const server = express();
const passport = require('passport');
const WindowsStrategy = require('passport-windowsauth');
server.use(passport.initialize());
// https://stackoverflow.com/questions/55296233/nodejs-express-passport-iis
passport.use('MyAuthStrategy', new WindowsStrategy({
    integrated: true
  },
  function(profile, done) {
    if (profile) {
user = profile;
return done(null, user);
}
else {
return done(null, false);
}
  }
));
//https://stackoverflow.com/questions/19948816/passport-js-error-failed-to-serialize-user-into-session
passport.serializeUser(function(user, done) {
  done(null, user);
});
passport.deserializeUser(function(user, done) {
  done(null, user);
});
const port = process.env.PORT || 3000;
// use windows-authentication
server.get('/',
passport.authenticate('MyAuthStrategy'),
function (req, res) {
    res.json(req.user);
});
server.listen(port, () => {
    console.log(`Listening on ${port}`);
});

And the web.config :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <appSettings>
        <!--
            All appSettings are made available to your Node.js app via environment variables
            You can access them in your app through the process.env object.
            
            process.env.<key>
        -->
        
       <!-- Unconmment the below appSetting if you'd like to use a Virtual Directory -->
       <!-- <add key="virtualDirPath" value="" /> -->
    </appSettings>
    <system.webServer>
        <!-- Remove the modules element if running on IIS 8.5-->
        <modules runAllManagedModulesForAllRequests="false" />
        <httpErrors existingResponse="PassThrough"></httpErrors>
        
        <iisnode node_env="%node_env%" nodeProcessCountPerApplication="1" maxConcurrentRequestsPerProcess="1024" maxNamedPipeConnectionRetry="100" namedPipeConnectionRetryDelay="250" maxNamedPipeConnectionPoolSize="512" maxNamedPipePooledConnectionAge="30000" asyncCompletionThreadCount="0" initialRequestBufferSize="4096" maxRequestBufferSize="65536" uncFileChangesPollingInterval="5000" gracefulShutdownTimeout="60000" loggingEnabled="true" logDirectory="iisnode" debuggingEnabled="true" debugHeaderEnabled="false" debuggerPortRange="5058-6058" debuggerPathSegment="debug" maxLogFileSizeInKB="128" maxTotalLogFileSizeInKB="1024" maxLogFiles="20" devErrorsEnabled="true" flushResponse="false" enableXFF="false" configOverrides="iisnode.yml" watchedFiles="web.config;*.js" nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
                 
        <!-- 
            Before the handlers element can work on IIS 8.5
            follow steps listed here https://github.com/tjanczuk/iisnode/issues/52 
        -->                 
        <handlers>
      <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
    </handlers>
        <rewrite>
            <rules>
                <!-- Don't interfere with requests for node-inspector debugging -->
                <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
                    <match url="^server.js\/debug[\/]?" />
                </rule>
                <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
                <rule name="StaticContent" patternSyntax="Wildcard">
                    <action type="Rewrite" url="public/{R:0}" logRewrittenUrl="true" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    </conditions>
                    <match url="*.*" />
                </rule>
                <!-- All other URLs are mapped to the Node.js application entry point -->
                <rule name="DynamicContent">
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
                    </conditions>
                    <action type="Rewrite" url="server.js" />
                </rule>
                <rule name="SocketIO" patternSyntax="ECMAScript">
                    <match url="socket.io.+" />
                    <action type="Rewrite" url="server.js" />
                </rule>
            </rules>
        </rewrite>
        <directoryBrowse enabled="true" />
        <security>
            <authentication>
                <anonymousAuthentication enabled="false" userName="IUSR" />
                <windowsAuthentication enabled="true" useKernelMode="true">
                    <extendedProtection tokenChecking="Allow" />
                    <providers>
                        <clear />
                        <add value="NTLM" />
                        <add value="Negotiate" />
                    </providers>
                </windowsAuthentication>
            </authentication>
        </security>
    </system.webServer>
    <system.web>
    <authentication mode="Windows" />
    <authorization>
        <allow users="*" />
    </authorization>
    <identity impersonate="false" />
</system.web>
</configuration>

Here the installed Features:

在此处输入图像描述

Any suggestions will be greatly appreciated. I really don't know what to do.

IIS-Website Keeps prompting for Credentials

After testing, I found that this situation will only appear when the wrong credentials are entered. So you must make sure to enter the correct windows credentials.

If you are using a domain account, you must also provide the domain where the domain account is located when providing credentials:

在此处输入图像描述

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM