Unauthorized when accessing custom admin endpoint

Hi folks,

Paul (@Paul-Reed) reported an issue about my new node-red-contrib-xterm node:

image
Would really to have it solved, since that is the last 'known' issue before I can publish my first version on NPM. But I'm stuck ...

I found out that I can reproduce the problem, by activating the (default) username and password in the settings.js file:

    adminAuth: {
        type: "credentials",
        users: [{
            username: "admin",
            password: "$2a$08$VPSeTFDg09qElIvYvD0MjOlK1zdgi0109kNB6.gWU7XC.y1/h0Hz2",
            permissions: "*"
        }]
    },

As a result of that change, my flow editor keeps loading (due to my xterm node) :woozy_face:

Found following details by debugging:

  1. Due to this change in the settings.js file, the needsPermissions function will initiate Bearer authentication:

  2. Afterwards we arrive in the Bearer authentication strategy function. For all Node-RED standard admin endpoint ajax calls (nodes, flows, settings, ...) this works fine, because those http requests all contain an "Authorization" http header (which will be used as Bearer token):

  3. However my custom xterm ajax call contains no such http Authorization header, so no token (so the Bearer authentication will fail):

But I don't know why my ajax call doesn't have that http header. Thought it would be added automatically, when the first request failed (i.e. status 401)?

Does anybody can give me a tip of what I could try?

Thanks a lot !!
Bart

  1. How have you defined the endpoint that serves that resource?
  2. How are you trying to load it?

Hey Nick,
I assume it must be something very stupid ...

  • My endpoint is defined here:

    RED.httpAdmin.get('/xterm_shell/:terminal_id/:command/:info', RED.auth.needsPermission('xterm.write'), function(req, res) {
    

    Although I think it must be a POST when I use permission 'xterm.write', and a GET for permission 'xterm.read'? But while writing this, I'm even not sure anymore whether it is correct (and secure) that I send the (terminal) input data to the server via the \:info part at the end of the url ...

  • That endpoint is called for example here:

    <script src="xterm_shell/undefined/static/xterm.js"></script>
    

    I have also some $.ajax... calls (like this one), but I haven't tested those yet with credentials...

No, its .read if its something a user with read-only access should have access to and .write if its something that requires full read/write access.

Do not equate read and write with get and post - there may be things that only a user with full access is allowed to read.

Any endpoint that has needsPermission will require the auth header to be set to access. jQuery is setup by us to add that header for any request - so your $.ajax requests will work.

The <script> loading of xterm.js won't work because the browser doesn't know to add the auth header.

In general though, loading static javascript resources don't need to be behind an endpoint protected by needsPermission. So the fix would be to add a separate endpoint for serving these resources and don't use needsPermission on it.

4 Likes

Thanks a lot again Nick!
That is very clear information. Will try it tomorrow and will get back here.
Have a nice sunday !

The separate endpoint for static resources (without needsPermission), has solved the problem for both me and Paul!

5 Likes