Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double login prompt - first in browser, second in popup. #3435

Closed
y8s opened this issue Feb 11, 2022 · 33 comments
Closed

Double login prompt - first in browser, second in popup. #3435

y8s opened this issue Feb 11, 2022 · 33 comments

Comments

@y8s
Copy link

y8s commented Feb 11, 2022

Current Behavior

When first logging in (or using incognito), I am presented with the standard Node-RED log Username: Password: and login button page

image

After logging in, I get the progress bar and "loading nodes" message and a second modal popup login box appears:

omg_whoops

Audit logs don't show any obvious difference whether I log into the second dialog or not.

So what is it?

Expected Behavior

Normal, single, nodered welcome page login. Just one time, without the need to deal with a second popup.

Steps To Reproduce

Load nodered web interface, log in as usual.

Example flow

example flow not applicable

Environment

  • Node-RED version: 1.3.5
  • Node.js version: v14.18.2
  • npm version: 6.14.15
  • Platform/OS: Raspberry Pi 400 / Debian 10 Buster
  • Browser: Chrome 9

8.0.4758.82

sample log where I cancel the second popup

first load page and log in with credentials:

11 Feb 12:34:19 - [audit] {"event":"auth.login","username":"admin","client":"node-red-editor","scope":"*","level":98,"timestamp":1644600859288}
11 Feb 12:34:19 - [audit] {"event":"plugins.list.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/plugins","ip":"192.168.1.200","timestamp":1644600859554}
11 Feb 12:34:19 - [audit] {"event":"comms.open","level":98,"timestamp":1644600859578}
11 Feb 12:34:19 - [audit] {"event":"comms.auth","user":{"username":"admin","permissions":"*"},"level":98,"timestamp":1644600859603}
11 Feb 12:34:19 - [audit] {"event":"plugins.configs.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/plugins","ip":"192.168.1.200","timestamp":1644600859634}
11 Feb 12:34:19 - [audit] {"event":"nodes.list.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/nodes","ip":"192.168.1.200","timestamp":1644600859665}
11 Feb 12:34:19 - [audit] {"event":"nodes.icons.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/icons","ip":"192.168.1.200","timestamp":1644600859743}
11 Feb 12:34:19 - [audit] {"event":"nodes.configs.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/nodes","ip":"192.168.1.200","timestamp":1644600859779}

hit cancel:

11 Feb 12:34:54 - [audit] {"event":"flows.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/flows","ip":"192.168.1.200","timestamp":1644600894457}

Here's the version where I enter the credentials in the popup

first load page and log in with credentials:

11 Feb 12:35:47 - [audit] {"event":"auth.login","username":"admin","client":"node-red-editor","scope":"*","level":98,"timestamp":1644600947179}
11 Feb 12:35:47 - [audit] {"event":"plugins.list.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/plugins","ip":"192.168.1.200","timestamp":1644600947485}
11 Feb 12:35:47 - [audit] {"event":"comms.open","level":98,"timestamp":1644600947518}
11 Feb 12:35:47 - [audit] {"event":"comms.auth","user":{"username":"admin","permissions":"*"},"level":98,"timestamp":1644600947559}
11 Feb 12:35:47 - [audit] {"event":"plugins.configs.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/plugins","ip":"192.168.1.200","timestamp":1644600947627}
11 Feb 12:35:47 - [audit] {"event":"nodes.list.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/nodes","ip":"192.168.1.200","timestamp":1644600947661}
11 Feb 12:35:47 - [audit] {"event":"nodes.icons.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/icons","ip":"192.168.1.200","timestamp":1644600947769}
11 Feb 12:35:47 - [audit] {"event":"nodes.configs.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/nodes","ip":"192.168.1.200","timestamp":1644600947798}

enter same credentials:

11 Feb 12:36:02 - [audit] {"event":"flows.get","level":98,"user":{"username":"admin","permissions":"*"},"path":"/flows","ip":"192.168.1.200","timestamp":1644600962993}
@hardillb
Copy link
Member

Can you include your settings.js details and any information about any reverse proxy you may have enabled

@y8s
Copy link
Author

y8s commented Feb 11, 2022

Settings.js scrubbed of secrets:
y8s_settings.js.txt

edit, sorry, here's the uncommented portion of my settings.js:

module.exports = {
    uiPort: process.env.PORT || 1880,
    mqttReconnectTime: 15000,
    serialReconnectTime: 15000,
    debugMaxLength: 1000,
    flowFilePretty: true,
    credentialSecret: "redacted",
    adminAuth: {
        type: "credentials",
        users: [{
            username: "admin",
            password: "redacted",
            permissions: "*"
        }]
    },

    httpNodeAuth: {user:"admin",pass:"redacted"},
    httpStaticAuth: {user:"admin",pass:"redacted"},
    functionGlobalContext: {
        // os:require('os'),
        // octalbonescript:require('octalbonescript'),
        // jfive:require("johnny-five"),
        // j5board:require("johnny-five").Board({repl:false})
    },

    logging: {
        console: {
            level: "warn",
            metrics: false,
            audit: true
        }
    }
}

Running Caddy server V2 with this in my config:

nodered.example.com {
  reverse_proxy  localhost:1880
  log {
    output file /var/log/caddy/nodered.example.com_access.log
    level ERROR
  }
}

I'm pretty sure this has been working fine until recently, but I haven't been paying attention. I did just update a few things and added node-red-contrib-homekit-bridged.

Thanks.

@hardillb
Copy link
Member

Node-RED in it's self should not be triggering any http basic Auth for anything in the editor.

You should be able to use the browser console (press f11) network tab to see which http request is replying with a 401 http status code at the point the pop-up that asks for the password shows up.

This will tell us what is triggering this

@y8s
Copy link
Author

y8s commented Feb 12, 2022

Not sure what I should be looking for but network tab shows it is nodered.example.com/settings.js

General
Request URL: https://nodered.example.com/settings.js
Request Method: GET
Status Code: 401 
Remote Address: 123.356.789.101:443  #my wan ip
Referrer Policy: strict-origin-when-cross-origin

Response Headers
access-control-allow-origin: *
content-length: 12
content-type: text/plain; charset=utf-8
date: Sat, 12 Feb 2022 17:13:21 GMT
etag: W/"gobbledeygook"
server: Caddy
www-authenticate: Basic realm="Authorization Required"
x-powered-by: Express

There might be a setting i'm missing in my caddy config, but I haven't really changed anything since it was working.

@hardillb
Copy link
Member

hardillb commented Feb 12, 2022

That will be the first 401 error and is expected, it's what triggers the editor to show the login form (not the popup) but it shouldn't have a www-authenticate: Basic realm="Authorization Required" header field it should be www-authenticate: Bearer realm="Users"

Can you check for any other 401 errors in the network tab

@knolleary
Copy link
Member

Looking closer, that isn't the expected request if it's for /settings.js rather than just /settings

@hardillb
Copy link
Member

doh, good point

@y8s
Copy link
Author

y8s commented Feb 12, 2022

question 1: does audit trace affect this?
question 2: is there something I could look for in a more fine log level?

@y8s
Copy link
Author

y8s commented Feb 12, 2022

new data point: I still get this using the local ip
e.g. http://192.168.1.42:1880

@knolleary
Copy link
Member

@y8s it doesn't matter what IP you use - something is requesting /settings.js and that is triggering the basic auth prompt. That is not a request being made by the core - it must be a contrib node doing it.

You mentioned you had recently added node-red-contrib-homekit-bridged. I've had a quick look through its code I can't see any reference to settings.js, so I don't think its at fault here.

In the Network tab, where you see the entry for /settings.js I think you should see an 'initiator' column. That should give you some hints as to what is making the call. It's hard to give you a precise set of instructions here - you may need to dig around bit.

@hardillb
Copy link
Member

I've managed to reproduce this with stock v1.3.5 and no extra nodes.

I'm having a bit of a poke round

@hardillb
Copy link
Member

OK, this might be a different problem I've reproduced

  • Using stock v1.3.5
  • Enable adminAuth
  • Enable httpNodeAuth
  • Open new incognito tab and open the debugger
  • Point Chrome at http://localhost:1880

Using Wireshark it appears that the httpNodeAuth is being attached to the route for /vendor/purify.min.js.map is triggering the httpNodeAuth route. This file is requested by the debugger (and only if the browser console is open) and doesn't show up in the Network tab.

I'm also seeing this just by reloading the page, I don't even have to log using the form to see the Basic Auth popup

@y8s
Copy link
Author

y8s commented Feb 12, 2022

my initiator chain looks like:

http://myip:1880
  http://myip:1880/vendor/vendor.js
    http://myip:1880/settings.js

I see references to red.min.js and main.min.js but there's a lot of lines and I don't see any that mention any kind of auth.

@knolleary
Copy link
Member

Can you take a screenshot? We aren't looking for anything mentioning Auth. We are looking for who is trying to load /settings.js

@y8s
Copy link
Author

y8s commented Feb 12, 2022

stacktrace.txt

Is this what you are looking for?

@y8s
Copy link
Author

y8s commented Feb 22, 2022

@knolleary Do you still need anything from me to help diagnose?

@knolleary
Copy link
Member

There isn't much I can do here. There is something outside of the core making a request to load /settings.js. This really needs some detective work to identify what that is - as we don't see this issue, we can't do that ourselves.

@dceejay
Copy link
Member

dceejay commented Feb 22, 2022

What ether extra nodes do you have installed ?

@y8s
Copy link
Author

y8s commented Feb 22, 2022

Here's everything and versions below.

node-red
1.3.5
node-red-contrib-batcher
1.0.0
node-red-contrib-bigtimer
2.8.1
node-red-contrib-counter
0.1.6
node-red-contrib-google-smarthome
0.2.9
node-red-contrib-harmony-websocket
2.2.6
node-red-contrib-home-assistant-websocket
0.38.0
node-red-contrib-homekit-bridged
1.4.3
node-red-contrib-hs100
1.0.2
node-red-contrib-looptimer-advanced
0.0.3
node-red-contrib-mysensors
3.3.1
node-red-contrib-mytimeout
3.2.0
node-red-contrib-play-audio
2.5.0
node-red-contrib-simpletime
2.10.0
node-red-contrib-tasmota
0.9.11
node-red-contrib-tplink
1.0.0
node-red-contrib-ui-led
0.4.9
node-red-contrib-unit-converter
0.0.2
node-red-contrib-zigbee2mqtt
2.0.5
node-red-dashboard
2.29.1
node-red-node-openweathermap
0.5.0
node-red-node-pi-gpio
2.0.1
node-red-node-ping
0.3.1
node-red-node-random
0.4.0
node-red-node-rbe
0.5.0
node-red-node-serialport
0.15.0
node-red-node-smooth
0.1.2
node-red-node-tail
0.3.1

I'm also running caddy reverse proxy https.

@bartbutenaers
Copy link
Contributor

Hey guys,
I have the same issue for quite some time, but have always thought it was a problem caused by myself. Which is why I had not logged it...

Will try to give some extra information, which perhaps rings a bell to someone. But perhaps not because it is all blurry info...

  • I get my Node-RED credentials popup, and - as soon I have entered my credentials are closed - the second popup occurs (but that is a browser credential popup).

  • When my Node-RED log credential popup is open and I start my developer tools, then the browser credential popup immediatly is displayed above my Node-RED popup:

    image

    So something triggers that browser popup when I open my developer tools...

  • I see a 401 in my browser log, but not sure if that is related to it:

    image

If there is anything I can test, don't hesitate to let me know!
Bart

@knolleary
Copy link
Member

@bartbutenaers if you read back on the questions we asked to debug this, it would be helpful to check the network tab to see if there are any other routes hitting a 401. The log message for settings is expected - that's how the editor knows it isn't logged in.

There was a suggestion of another request for settings.js that was also hitting a 401 and triggering the basic Auth challenge. What we don't know is where that request is coming from. It isn't one we recognise in the core.

@bartbutenaers
Copy link
Contributor

bartbutenaers commented Feb 22, 2022

In the following screenshot you see the Network tabsheet, at the moment when the Node-RED dialog is still open but I have already filled in the credentials in the native browser popup at this point:

image

All statusses are 200 except that one 401...

When I get the native popup and I clear the network tabsheet (before I enter the credentials in it), then I would have expected to see requests appearing in the network tabsheet. But even if I enter multiple times wrong credentials in my native popup, nothing shows up in my cleared network tabsheet:

image

Very weird...

@y8s
Copy link
Author

y8s commented Feb 22, 2022

@knolleary It is the dashboard. The popup is the same as the auth for the dashboard/ui.

If I go to the dashboard (www.example.com/ui) and log in, when I return to just nodered.example.com, the prompt does not appear.

Unfortunately removing all dashboard / ui elements from my palette does NOT fix the issue. I can still go to /ui and log in and then no matter how many times I reload the flows it doesn't prompt me.

To reproduce:
Open a new incognito or similar window. Load nodered. See the double prompt. Cancel out of the second popup.
Open a new tab in that incognito window to /ui and log in (same credentials as nodered login for me)
Return to first tab and reload. loading progress bar will make it all the way with no additional popup.
Also if I close the node red flows and leave the UI tab open and then open a new flows tab, the session is preserved and I don't get the double prompt.
If I close all incognito tabs and start over, the pop-up prompt returns.

@knolleary
Copy link
Member

I'm not 100% sure that's the evidence you believe it to be. Yes the httpNodeAuth setting enables basic Auth and is what you can use to secure the dashboard. But that doesn't mean it is the dashboard that is causing that prompt.

Internally, there are two sections to the http route handling:

  1. httpNode is used by the HTTP In nodes, Dashboard.. anything that a flow exposes.
  2. httpAdmin is used by any routes related to the editor and is secured by adminAuth.

To trigger the basic Auth dialog, something is making a request to a route hosted by httpNode.

If you open the dashboard, it triggers the prompt because it is a httpNode hosted route. When you go back to the editor, the Auth session still exists so you don't get the second prompt.

This is why we need to identify what request is triggering the prompt. Because that means something is making a request to an httpNode hosted route whilst loading the editor (which should be purely hosted on the httpAdmin side of things)

@y8s
Copy link
Author

y8s commented Feb 22, 2022

ok. I tried to look at the trace log and see what I could but it doesn't show that much detail.

Are there any other ways to step through the loading of each node?

@hardillb
Copy link
Member

@bartbutenaers if you close the developer console while the browser credentials pop up is visible does it disappear? If so this is the thing I mentioned earlier (#3435 (comment)) about the dev tools trying to load a .map file for one of the .js files which triggers the httpNodeAuth middleware. This request never shows up in the chrome devTools network tab. (you do get a message in the console if you enter the right username/password about it 404ing)

This is really not helpful as it means that chrome behaves differently if you try to debug it (and it hides that request from it's own debug logs). If I use Firefox's debug tools I do not get this extra request. (it appears you can turn off source map loading in the devTools settings)

Actually that might be something for @y8s to try. Can you use a different browser e.g. FireFox and see if it can provide a better stack trace for the 401 request for settings.js?

@y8s
Copy link
Author

y8s commented Feb 23, 2022

vendor.js line 42 has something about basic auth.
stack trace in firefox dev didn't reveal anything different.

ffstacktrace.txt

@bartbutenaers
Copy link
Contributor

@hardillb: interesting theory! I can confirm that the popup appears in Chrome every time I open the Developer Tools, and the popup disappears again when I close the Developer Tools. I can repeat this as often as I want. And the same effect in Edge Chromium. In Firefox I got no popup at all like you say.

Did another experiment, but not sure if the result is of any use:

  1. The native popup occurs.

  2. In my developer tools I click on the pauze button, to pauze my debugger at the next statement that will be executed (which I assume is immediately after my popup):

    image

  3. Since I cannot pauze before the popup (and only after it), I tried to force a loop: by entering incorrect credentials I know that I will again get such a popup. This means that the code - responsible for the popup appearing - will again be executed.

  4. When I click the "login" button, the debugger wil halt here:

    image

  5. One step further I arrive here:

    image

    Not sure whether that node-logon-dialog-login-username is relevant somehow?

  6. The remaining code isn't really learning me something unfortunately, so I did not manage to arrive at the code where the popup is triggered ;-(

So I did another experiment:

  1. The native popup appears.

  2. I start the Chrome profiler

  3. I enter incorrect credentials and click the "Login" button

  4. The native popup appears again.

  5. I stop the Chrome profiler, which should have only recorded function calls in between my two popups. So I hope that the responsible code is somewhere in between. But not sure...

  6. This is the resulting profile:

    image

Not sure at this moment where I should look at ...

@y8s
Copy link
Author

y8s commented Apr 22, 2022

So I copied my .node-red directory to a new location and spun up a second instance and started removing things.

it's node-red-contrib-zigbee2mqtt that's causing the login popup.

I haven't dug into it more yet.

@y8s
Copy link
Author

y8s commented Apr 27, 2022

@y8s it doesn't matter what IP you use - something is requesting /settings.js and that is triggering the basic auth prompt. That is not a request being made by the core - it must be a contrib node doing it.

You mentioned you had recently added node-red-contrib-homekit-bridged. I've had a quick look through its code I can't see any reference to settings.js, so I don't think its at fault here.

In the Network tab, where you see the entry for /settings.js I think you should see an 'initiator' column. That should give you some hints as to what is making the call. It's hard to give you a precise set of instructions here - you may need to dig around bit.

@knolleary Is this HTML file to blame?: node-red-contrib-zigbee2mqtt/nodes/bridge.html

the first line is <script src="../../../settings.js"></script>

And if so, what should it be?

@knolleary
Copy link
Member

Yes that line is to blame.

And if so, what should it be?

You would have to ask the maintainer of the node what they are trying to do with that line. They have clearly added it for a reason - but it would never have worked.

@y8s
Copy link
Author

y8s commented Apr 27, 2022

Yes that line is to blame.

And if so, what should it be?

You would have to ask the maintainer of the node what they are trying to do with that line. They have clearly added it for a reason - but it would never have worked.

I started an issue there so hopefully they can figure it out.

@y8s
Copy link
Author

y8s commented May 27, 2022

node-red-contrib-zigbee2mqtt@2.2.5
fixed. closing.

@y8s y8s closed this as completed May 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants