Nextcloud Oauth 2 Login

I'm trying to log into my Node-red instance using Nextcloud 14's new Oath2 implementation. I get through the login with nextcloud and get re-directed to the callback url
https://example.tld/node-red/auth/strategy/callback?state=&code=################################################################################################################################ but then I just get re-directed back to the node-red login screen

Nginx settings for node-red

  #############
  # Node-Red  #
  #############
  location ^~ /node-red/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:1880/node-red/;
  }

my settings.js based off the passport-oauth2 example

  adminAuth: {
        type:"strategy",
        strategy: {
            name: "oauth2",
            label: 'Sign in with nextcloud',
            icon:"fa-cloud",
            strategy: require("passport-oauth2").Strategy,
            options: {
              authorizationURL: "https://example.tld/apps/oauth2/authorize",
              tokenURL: "https://example.tld/apps/oauth2/api/v1/token",
              clientID: "#####################################################################",
              clientSecret: "#####################################################################",
              callbackURL: "https://example.tld/node-red/auth/strategy/callback",
              proxy: true
            },
            verify: function(accessToken, refreshToken, profile, done) {
                done(null, profile);
            }
       },
       users: [{
            username: "dugite.code",
            permissions: ["*"]
        }]
    },

Looking at this guy's gitlab login example it should all be possible:
https://www.claudiuscoenen.de/2018/10/oauth2-with-nextcloud-provider-and-gitlab-client/

There is a user information url available but passport didn't call for it.
"user_info_url" : "/ocs/v2.php/cloud/user?format=json"

I'm probably missing somethings simple

That is where the OAuth process sends you once you are authenticated. So it needs to point at Node-RED. If you are on a local network, it might be something like:

https://192.168.1.20:1880/auth/strategy/callback

or whatever your normal URL is.

I am not sure, however, whether the path is influenced by other settings. For example, my admin interface tends to be on /red. The docs imply that it is impacted. So, for me, it might be something like:

https://192.168.1.20/red/auth/strategy/callback

Once you get it sorted, it might be handy for others if you were to submit a PR against the docs to clarify things.

I'm not sure I understand what your saying?
"https://example.tld/node-red/auth/strategy/callback" is pointing to my node-red instance

I added my nginx config as that might be one of the issues

I also added proxy: true to the options field as suggested here

Ok so Reading here it looks like I do need to call "/ocs/v2.php/cloud/user?format=json" url somehow in order to actually get the username for the profile object.

Don't know how to do that yet

One issue I've had when doing something similar for dokuwiki is the empty state nextcloud issues Don't know if this will trip me up.

As Gitlab oauth2 is similar to nextcloud I'm looking at this to see if it will provide any hints

So I recently switched to using authentk for sso and in follow up to this topic I figured out I can use the node-fetch module to call the user profile endpoint in the verify function.

This should give anyone looking into this topic a better place to start

verify: function(accessToken, refreshToken, profile, done) {
    const fetch = require('node-fetch');
    const Options = {
        headers: {
        'Accept': 'application/json',
         'Authorization': accessToken
        },
    }
    fetch('https://example.tld/ocs/v2.php/cloud/user?format=json')
        .then(response => {
            console.log(response);
            var json = JSON.parse(response).attributes;
            console.log(json);
        )
}

I'm currently struggling to get the user info in authentik as I'm getting unauthorized errors when calling the userinfo endpoint. The more things change the more they stay the same :sweat_smile:

Finally got user accounts using authentik. Now I just need to get group based permissions at some point.

SSO Using Authentik

Preparation

The following placeholders will be used:

authentik.company is the FQDN of authentik.
nodered.company is the FQDN of nodered.

Step 1

In authentik, create an OAuth2/OpenID Provider (under Resources/Providers) with these settings:

note

Only settings that have been modified from default have been listed.

Protocol Settings

Name: nodered
Signing Key: Select any available key

note

Take note of the Client ID and Client Secret, you'll need to give them to nodered in Step 3.

Step 2

In authentik, create an application (under Resources/Applications) which uses this provider. Optionally apply access restrictions to the application using policy bindings.
note

Only settings that have been modified from default have been listed.

Name: nodered
Slug: nodered-slug
Provider: nodered

Step 3

note

We are assuming node-red is installed under docker

Navigate to the node-red data volume data/node_modules/. Alternatively enter the docker container sudo docker exec -it nodered bash and cd /data/node_modules

Use npm to install passport-openidconnect npm install passport-openidconnect

Edit the node-red settings.js file /data/settings.js

adminAuth: {
type:"strategy",
strategy: {
        name: "openidconnect",
        label: 'Sign in with authentik',
        icon:"fa-cloud",
        strategy: require("passport-openidconnect").Strategy,
        options: {
                issuer: 'https://authentik.company/application/o/<application-slug>/',
                authorizationURL: 'https://authentik.company/application/o/authorize/',
                tokenURL: 'https://authentik.company/application/o/token/',
                userInfoURL: 'https://authentik.company/application/o/userinfo/',
                clientID: '<Client ID (Key): Step 2>',
                clientSecret: '<Client Secret: Step 2>',
                callbackURL: 'https://nodered.company/auth/strategy/callback/',
                scope: ['email', 'profile', 'openid'],
                proxy: true,
        verify: function(issuer, profile, done) {
                done(null, profile)
        }
      }
    },
    users: function(user) {
        return Promise.resolve({ username: user, permissions: "*" });
    }
},
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.