SciCatProject / backend-v3

SciCat Data Catalogue Backend
https://scicatproject.github.io/documentation/
BSD 3-Clause "New" or "Revised" License
13 stars 17 forks source link

OIDC Login fails with express-session Error #691

Closed belfhi closed 2 years ago

belfhi commented 2 years ago

OIDC Login fails

Summary

I set up scicat in a kubernetes deployment and want to use Keycloak as OIDC auth provider. I turned off the login fields and configured the paths in the frontend and the provider in providers.json but when I click on the sign in with Keycloak button I get a 500 Internal Server Error:

Unhandled error for request GET /auth/keycloak: Error: OpenID Connect requires session support. Did you forget to use `express-session` middleware?
    at SessionStore.store (/home/node/app/node_modules/passport-openidconnect/lib/state/session.js:39:33)
    at Strategy.authenticate (/home/node/app/node_modules/passport-openidconnect/lib/strategy.js:358:24)
    at attempt (/home/node/app/node_modules/passport/lib/middleware/authenticate.js:366:16)
    at authenticate (/home/node/app/node_modules/passport/lib/middleware/authenticate.js:367:7)
    at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/node/app/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/node/app/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5)
    at /home/node/app/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/node/app/node_modules/express/lib/router/index.js:335:12)
    at next (/home/node/app/node_modules/express/lib/router/index.js:275:10)
    at urlencodedParser (/home/node/app/node_modules/body-parser/lib/types/urlencoded.js:91:7)
    at Layer.handle [as handle_request] (/home/node/app/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/node/app/node_modules/express/lib/router/index.js:317:13)
    at /home/node/app/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/node/app/node_modules/express/lib/router/index.js:335:12)

Steps to Reproduce

my providers.json snippet is:

        "keycloak": {
            "session": false,
            "provider": "oidc",
            "authScheme": "openid connect",
            "module": "/home/node/app/server/boot/oidcCompatibleStrategy",
            "authPath": "/auth/keycloak",
            "issuer": "https://XXXX/auth/realms/testing",
            "clientID": "XXXXX,
            "clientSecret": "XXXXX",
            "callbackURL": "/auth/keycloak/callback",
            "authorizationURL": "https://XXXX/auth/realms/testing/protocol/openid-connect/auth",
            "tokenURL": "https://XXXX/auth/realms/testing/protocol/openid-connect/token",
            "userInfoURL": "https://XXXX/auth/realms/testing/protocol/openid-connect/userinfo",
            "scope":   ["openid","profile","email"],
            "callbackPath": "/auth/keycloak/callback",
            "successRedirect": "/user",
            "failureRedirect": "/login",
            "failureFlash": true
      }

Current Behaviour

no redirect to Keycloak, but internal server error.

Expected Behaviour

redirect to OIDC Provider (Keycloak) and after successful authentication redirect back to scicat.

Extra Details

Here you should include details about the system (if it is unique) and possible information about a fix (feel free to link to code where relevant). Screenshots/GIFs are also fine here.

J-avery32 commented 2 years ago

I am getting the same error when following the tutorial for google OIDC: https://scicatproject.github.io/documentation/Development/OIDC.html This is with docker.

belfhi commented 2 years ago

So. I looked into the code and:

server/server.js lines 20+

// express sessions are required for passport ocid. If your
// config.Local has a session for the expressionSecret, configure
// express-session
if (configLocal.expressSessionSecret){
  var session = require("express-session");
  app.use(session({
    secret: configLocal.expressSessionSecret,
    resave: false,
    saveUninitialized: true
  }));
}

So it seems like expressSessionSecret needs to be set in config.local.js. A first test confirms that and now gives different errors
Unhandled error for request GET /api/v3/Users/62fb4944304d14f82fc002cb: Error: Authorization Required but the Keycloak part seems to be working. Cheers

J-avery32 commented 2 years ago

That worked for me as well. @belfhi maybe we should keep this issue open so that we can request for better documentation in the tutorial about setting the express session secret?

J-avery32 commented 2 years ago

Never mind. It looks like it is in the documentation.

belfhi commented 2 years ago

Yes, my PR was merged after I found out about the issue 😅

J-avery32 commented 2 years ago

Do you know what solved this: /api/v3/Users/62fb4944304d14f82fc002cb: Error: Authorization Required?

belfhi commented 2 years ago

Try this callback function

"use strict";

exports.accessGroupsToProfile =
  function (req, done) {
    return function (err, user, identity, token) {
      identity.updateAttributes({ 
        "profile": {
          accessGroups: identity.profile._json.groups,
          email: identity.profile._json.email,
          ...identity.profile
        }, 
        "credentials": null });
      var authInfo = {
        identity: identity,
      };
      if (token) {
        authInfo.accessToken = token;
      }
      done(err, user, authInfo);
    };
  };

In keycloak you need to map the users' groups to the groups claim and then login should work. Don't forget to reference the function in the providers.json file