Cannot use Azure AD Authentication

Hello guys! I'm trying to put authentication through azure as shown here in the documentation:

nodered.org/docs/user-guide/runtime/securing-node-red#oauthopenid-based-authentication

Based on these examples:

My adminAuth object is shown below:

  adminAuth: {
    type: "strategy",
    strategy: {
      name: "azuread-openidconnect",
      label: "Sign in with Azure AD",
      icon: "fa-windows",
      strategy: require("passport-azure-ad").OIDCStrategy,
      options: {
        identityMetadata: `https://login.microsoftonline.com/${process.env.MICROSOFT_AUTH_TENANT_ID}/v2.0/.well-known/openid-configuration`,
        clientID: process.env.MICROSOFT_AUTH_CLIENT_ID,
        clientSecret: process.env.MICROSOFT_AUTH_CLIENT_SECRET,
        responseType: "code",
        responseMode: "query",
        redirectUrl: "https://localhost:1880/auth/strategy/callback",
        allowHttpForRedirectUrl: true,
        issuer: `https://login.microsoftonline.com/${process.env.MICROSOFT_AUTH_TENANT_ID}/v2.0`,
        scope: ["openid", "profile"],
        verify: function (token, tokenSecret, profile, done) {
          profile.username = profile.displayName; // use display name as username
          done(null, profile);
        },
      },
    },
    users: function (user) {
      return Promise.resolve({ username: user, permissions: "*" });
    },
  },

I'm trying to create a custom Docker image that uses this settings file, when I start node-red I get the following terminal output:

nodered-custom | 
nodered-custom | > node-red-custom@0.0.1 start /usr/src/node-red
nodered-custom | > node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS --userDir=/data
nodered-custom | 
nodered-custom | Error loading settings file: /data/settings.js
nodered-custom | 
nodered-custom | โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
nodered-custom | โ”‚                    npm update check failed                    โ”‚
nodered-custom | โ”‚              Try running with sudo or get access              โ”‚
nodered-custom | โ”‚             to the local update config store via              โ”‚
nodered-custom | โ”‚ sudo chown -R $USER:$(id -gn $USER) /usr/src/node-red/.config โ”‚
nodered-custom | โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
nodered-dblab exited with code 0

When I use a configuration file as shown below:

adminAuth: require("./user-authentication"),

And following the example of the documentation, it works

nodered.org/docs/user-guide/runtime/securing-node-red#custom-user-authentication

It also works when I use an username and password based authentication

nodered.org/docs/user-guide/runtime/securing-node-red#usernamepassword-based-authentication

Using the twitter example found in docs, it doesn't work and I get the same errors bellow

adminAuth: {
    type:"strategy",
    strategy: {
        name: "twitter",
        label: 'Sign in with Twitter',
        icon:"fa-twitter",
        strategy: require("passport-twitter").Strategy,
        options: {
            consumerKey: TWITTER_APP_CONSUMER_KEY,
            consumerSecret: TWITTER_APP_CONSUMER_SECRET,
            callbackURL: "http://example.com/auth/strategy/callback",
            verify: function(token, tokenSecret, profile, done) {
                done(null, profile);
            }
        },
    },
    users: [
       { username: "knolleary",permissions: ["*"]}
    ]
}

Can anyone help me try to solve this problem to correctly configure authentication?

The error message doesn't seem to be directly related to the Azure AD authentication. Instead, there may be something wrong with the base node.js / npm installation (permission problem?). Can you install any other external module?

It looks like you are using a custom container image. Have you tried with the original one? How do you get the external dependencies installed? I'm using an init container on Kubernetes.

1 Like

It looks like you are using a custom container image:

Yeah, I'm using a custom container image, but this image is based on an official image. External dependencies are being declared in package.json and installed on Dockerfile after using an official image, I copy also some files like settings.js, flows.js... and I want to use them to build an image with my preferences.

This is my dependences in package.json:

"dependencies": {
    "node-red": "2.2.0",
    "node-red-contrib-influxdb": "0.6.1",
    "node-red-contrib-telegrambot": "11.6.0",
    "node-red-dashboard": "3.2.0",
    "passport-azure-ad": "3.0.8"
  },

And I use passaport-azure-ad in adminAuth in settings.js:

  adminAuth: {
    type: "strategy",
    strategy: {
      name: "azuread-openidconnect",
      label: "Sign in with Azure AD",
      icon: "fa-windows",
      strategy: require("passport-azure-ad").OIDCStrategy,
      options: {
        identityMetadata: `https://login.microsoftonline.com/${process.env.MICROSOFT_AUTH_TENANT_ID}/v2.0/.well-known/openid-configuration`,
        clientID: process.env.MICROSOFT_AUTH_CLIENT_ID,
        clientSecret: process.env.MICROSOFT_AUTH_CLIENT_SECRET,
        responseType: "code",
        responseMode: "query",
        redirectUrl: "https://localhost:1880/auth/strategy/callback",
        allowHttpForRedirectUrl: true,
        issuer: `https://login.microsoftonline.com/${process.env.MICROSOFT_AUTH_TENANT_ID}/v2.0`,
        scope: ["openid", "profile"],
        verify: function (token, tokenSecret, profile, done) {
          profile.username = profile.displayName; // use display name as username
          done(null, profile);
        },
      },
    },
    users: function (user) {
      return Promise.resolve({ username: user, permissions: "*" });
    },
  },

I don't know if this is the right way to install this dependency, I made this way cause when I use a hash based auth, I can start the application and see the blocks loaded.

...

adminAuth: require("./user-authentication"),

...

user-authentication.js:

module.exports = {
  type: "credentials",
  users: function (username) {
    return new Promise(function (resolve) {
      if (username) {
        const user = { username, permissions: "*" };
        resolve(user);
      } else {
        resolve(null);
      }
    });
  },
  authenticate: function (username, password) {
    return new Promise(function (resolve) {
      const teste = username === "admin" && password === "pass";

      if (teste) {
        console.info("Authenticated!");
        
        var user = { username: "admin", permissions: "*" };
        resolve(user);
      } else {
        resolve(null);
      }
    });
  },
  default: function () {
    return new Promise(function (resolve) {
      resolve(null);
    });
  },
};

So I can install the dependencies as shown in image below, I don't know if to install passport-azure-ad it would be like this.

image

When I attach shell on docker image above I can see passport-azure-ad installed:

~/node_modules/passport-azure-ad $ ls
CHANGELOG.md        README.md           contributing.md     package.json
Gruntfile.js        RELEASES.md         lib                 test
LICENSE             SECURITY-NOTICE.MD  node_modules        typings

I used your config in adminAuth but I think we did the process in different ways :smiley:

Thank you for your attention and I am available to answer any questions you may have.