Ylianst / MeshCentral

A complete web-based remote monitoring and management web site. Once setup you can install agents and perform remote desktop session to devices on the local network or over the Internet.
https://meshcentral.com
Apache License 2.0
4.08k stars 549 forks source link

OIDC authentication causes critical error #6132

Closed xcsdm closed 4 months ago

xcsdm commented 4 months ago

Describe the bug Starting in version 1.1.22 and remaining in 1.1.24, OpenID/OIDC logins redirect to authentication server correctly, but the return to "https://mesh.example.com/oidc-callback?code=[redacted]" fails. In the case of using nginx reverse proxy, the error is "502 Bad Gateway".

Meshcentral restarts after this crash.

To Reproduce Steps to reproduce the behavior:

  1. Attempt login using OIDC

Expected behavior Succesful login presenting the meshcentral dashboard

Error in mesherrors.txt

-------- 5/28/2024, 1:39:35 PM ---- 1.1.24 --------

/opt/meshcentral/meshcentral/node_modules/passport/lib/middleware/authenticate.js:134
          req.flash(type, msg);
              ^

TypeError: req.flash is not a function
    at allFailed (/opt/meshcentral/meshcentral/node_modules/passport/lib/middleware/authenticate.js:134:15)
    at attempt (/opt/meshcentral/meshcentral/node_modules/passport/lib/middleware/authenticate.js:183:28)
    at strategy.fail (/opt/meshcentral/meshcentral/node_modules/passport/lib/middleware/authenticate.js:314:9)
    at /opt/meshcentral/meshcentral/node_modules/openid-client/lib/passport_strategy.js:198:12
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v20.12.1

Server Software (please complete the following information):

Client Device (please complete the following information):

Remote Device (please complete the following information): N/A

Additional context Add any other context about the problem here.

Your config.json file

{
  "$schema": "https://raw.githubusercontent.com/Ylianst/MeshCentral/master/meshcentral-config-schema.json",
  "settings": {
    "plugins":{"enabled": false},
    "_mongoDb": null,
    "cert": "redacted",
    "_WANonly": true,
    "_LANonly": true,
    "sessionKey": "redacted",
    "port": 443,
    "_aliasPort": 443,
    "redirPort": 80,
    "_redirAliasPort": 80,
    "AgentPong": 300,
    "TLSOffload": true,
    "SelfUpdate": false,
    "AllowFraming": false,
    "WebRTC": false,
    "_trustedProxy": "CloudFlare",
    "trustedProxy": "10.0.42.253",
    "_ignoreAgentHashCheck": true
  },
  "domains": {
    "": {
      "_title": "MyServer",
      "_title2": "Servername",
      "minify": true,
      "NewAccounts": false,
      "authStrategies": {
        "oidc": {
          "authorizationURL": "https://auth.example.com/application/o/authorize/",
          "callbackURL": "https://mesh.example.com/oidc-callback",
          "clientid": "redacted",
          "clientsecret": "redacted",
          "issuer": "https://auth.example.com/application/o/meshcentral/",
          "tokenURL": "https://auth.example.com/application/o/token/",
          "userInfoURL": "https://auth.example.com/application/o/userinfo/",
          "logoutURL": "https://auth.example.com/application/o/meshcentral/end-session/",
          "NewAccounts": true
        }
      },
      "localSessionRecording": false,
      "_userNameIsEmail": true,
      "certUrl": "https://mesh.example.com",
      "cert": "*.example.com"
    }
  },
  "_letsencrypt": {
    "__comment__": "Requires NodeJS 8.x or better, Go to https://letsdebug.net/ first before>",
    "_email": "myemail@mydomain.com",
    "_names": "myserver.mydomain.com",
    "production": false
  }
}

docker-compose.yml

#version: '3'

networks:
  meshcentral-tier:
    driver: bridge

services:
  mongodb:
    restart: always
    container_name: mongodb
    image: mongo:latest
    env_file:
      - .env
    volumes:
      # mongodb data-directory - A must for data persistence
      - ./meshcentral/mongodb_data:/data/db
    networks:
      - meshcentral-tier

  meshcentral:
    restart: always
    container_name: meshcentral
    # use the official meshcentral container
    image: ghcr.io/ylianst/meshcentral:latest
    #image: ghcr.io/ylianst/meshcentral:1.1.21
    depends_on:
      - mongodb
    ports:
      # MeshCentral will moan and try everything not to use port 80, but you can also use it if you so desire, just change the config.json according to your needs
      - 8086:443
    env_file:
      - .env
    volumes:
      # config.json and other important files live here. A must for data persistence
      - ./meshcentral/data:/opt/meshcentral/meshcentral-data
      # where file uploads for users live
      - ./meshcentral/user_files:/opt/meshcentral/meshcentral-files
      # location for the meshcentral-backups - this should be mounted to an external storage
      - ./meshcentral/backup:/opt/meshcentral/meshcentral-backups
      # location for site customization files
      - ./meshcentral/web:/opt/meshcentral/meshcentral-web
    networks:
      - meshcentral-tier
si458 commented 4 months ago

Hmm this should already be fixed? Check the /opt/meshcentral/package.json it should include connect-flash if I remember?

Will check soon when laptops switched on

Edit. Pr here for the fix? https://github.com/Ylianst/MeshCentral/commit/1dca9e2235ee0ef87afb6d337abdffb98e0d92ec

xcsdm commented 4 months ago

I can see

"connect-flash": "0.1.1",

in the dependencies. This is /opt/meshcentral/meshcentral/package.json in the docker container. and connect-flash is definitely in the node-modules.

Edit. The changes from the pr are confirmed in the meshcentral.js

si458 commented 4 months ago

ok so im confused why you get this error? as normally it just means that package is missing but im guessing its been removed somewhere! will have a look soon

timcanty commented 4 months ago

We are having the same issue, just haven't had the opportunity to look into it, after the service restarts, and you go back to the login page, it goes straight in, so feels like the return page that the oidc hits, is the one missing the required function

si458 commented 4 months ago

erm just re-read ur issue, the error is erroring inside the node_modules of passport.js so is nothing to do with meshcentral! which is quite worrying?

si458 commented 4 months ago

just out of curiosity, try setting ur config like below (i use authentik for my testing)

"authStrategies": {
        "oidc": {
            "issuer": {
                "issuer": "https://auth.myserver.com/application/o/meshcentral-oidc/",
                "authorization_endpoint": "https://auth.myserver.com/application/o/authorize/",
                "token_endpoint": "https://auth.myserver.com/application/o/token/",
                "endsession_endpoint": "https://auth.myserver.com/application/o/meshcentral-oidc/end-session/",
                "jwks_uri": "https://auth.myserver.com/application/o/meshcentral-oidc/jwks/"
            },
            "client": {
              "client_id": "CLIENTIDHERE",
              "client_secret": "CLIENTSECRETHERE
            },
            "newAccounts": true
        }
      }

OR try the basic config here - https://ylianst.github.io/MeshCentral/meshcentral/openidConnectStrategy/#basic-config-file-example

si458 commented 4 months ago

ok i think ive found the issue, but need you to confirm for me (as i cannot replicate the issue but think i found why its missing) line 6768 inside /opt/meshcentral/meshcentral/webserver.js just under parent.authLog('setupHTTPHandlers', `OIDC: Authorization URL: ${authURL}`); you need to add obj.app.use(require('connect-flash')()); then restart the meshcentral container (dont redeploy, just restart it!) and try again

xcsdm commented 4 months ago

Close.

First, it did allow login. If I click a PC, then click the "My Devices" icon (top on left), works as expected. If I click on a PC, then click Back in the browser, I get "Internal Server Error" with this logged:

meshcentral  | MeshCentral HTTP redirection server running on port 80.
meshcentral  | MeshCentral v1.1.24, Hybrid (LAN + WAN) mode, Production mode.
meshcentral  | MeshCentral Intel(R) AMT server running on mesh.xcsdm.com:4433.
meshcentral  | Loaded web certificate from "https://mesh.xcsdm.com", host: "mesh.xcsdm.com"
meshcentral  |   SHA384 cert hash: 2a2d2e8b92d3c69e6ea937016c3dd638a3f6fe5c0c86f3a17ec2fe063d6f640a8643d4085c1e264164b5341323cfef19
meshcentral  |   SHA384 key hash: 4700277a409aa747e0b1ac2922a010da2099c20a269b1c6cd97a4001cc1505709a6470b8ad5526d16fd41d272bf2b256
meshcentral  | MeshCentral HTTP server running on port 443.
meshcentral  | ERR: Error: did not find expected authorization request details in session, req.session["oidc:auth.xcsdm.com"] is undefined
meshcentral  |     at /opt/meshcentral/meshcentral/node_modules/openid-client/lib/passport_strategy.js:132:13
meshcentral  |     at OpenIDConnectStrategy.authenticate (/opt/meshcentral/meshcentral/node_modules/openid-client/lib/passport_strategy.js:191:5)
meshcentral  |     at attempt (/opt/meshcentral/meshcentral/node_modules/passport/lib/middleware/authenticate.js:378:16)
meshcentral  |     at authenticate (/opt/meshcentral/meshcentral/node_modules/passport/lib/middleware/authenticate.js:379:7)
meshcentral  |     at /opt/meshcentral/meshcentral/webserver.js:6787:124
meshcentral  |     at Layer.handle [as handle_request] (/opt/meshcentral/meshcentral/node_modules/express/lib/router/layer.js:95:5)
meshcentral  |     at next (/opt/meshcentral/meshcentral/node_modules/express/lib/router/route.js:149:13)
meshcentral  |     at urlencodedParser (/opt/meshcentral/meshcentral/node_modules/body-parser/lib/types/urlencoded.js:91:7)
meshcentral  |     at Layer.handle [as handle_request] (/opt/meshcentral/meshcentral/node_modules/express/lib/router/layer.js:95:5)
meshcentral  |     at next (/opt/meshcentral/meshcentral/node_modules/express/lib/router/route.js:149:13)
si458 commented 4 months ago

@xcsdm that will be because when you press the back button its returning you back to the reauth page which will be invalid because you are already logged in/missing authentication.

can you just try changing ur config.json to look like the above for me and restarting? https://github.com/Ylianst/MeshCentral/issues/6132#issuecomment-2135835070

si458 commented 4 months ago

@xcsdm ok i can replicate ur Error: did not find expected authorization request details in session issue i get the same thing, not too sure why? will look into it, but will push the fix for the auth login for you!

xcsdm commented 4 months ago

Sorry I did not mention. I did change the config to match your example. Login works fine. I can remote control PCs, etc.

si458 commented 4 months ago

@xcsdm ah right no worries! will look into the Error: did not find expected authorization request details in session as soon as i can again as you use docker you can use the master image as it includes fixes 👍 (this image is build every time we push something to the master branch for people to test or use the latest features!)

si458 commented 4 months ago

commit to fix the redirect if someone tries to return auth but no user/cookie/etc... https://github.com/Ylianst/MeshCentral/commit/62199d805721ac974b9d5ff74b9133ccf6446cb7

si458 commented 4 months ago

ok ive fixed the reauth problem! https://github.com/Ylianst/MeshCentral/commit/c67a76bcc27bfe2b62b9043e8dddec5ba0a8b449 basically when u first hit the oidc callback from your provider you have session info, but when u try hitting the page again (by say pressing back history) the session info had vanished as you are already logged in and verified. so just need to do a check to carry on if you already authed!

xcsdm commented 4 months ago

After pulling the lastest master docker image, all OIDC login attempts are redirected to the main login page.

Steps: Open https://mesh.example.com/auth-oidc (or just click the OIDC login button on the login page) Auth server performs authentication (Authentik in my case) and redirects to [server]/auth-oidc-callback?[many parameters omitted here] Am redirected to https://mesh.example.com/

No errors in the meshcentral container log No errors or messages in the authlog

If I simply open https://mesh.example.com/auth-oidc-callback the error "LOGIN FAILED: REQUEST CONTAINS NO USER OR SID" is logged in authlog, so logging itself appears to be working.

Could this be the failureredirect on line 6789?