Uninstall CAS and Ldap
$ npm uninstall kth-node-ldap kth-node-passport-cas
Install kth-node-passport-oidc
$ npm install @kth/kth-node-passport-oidc
Remove
const devLdap = undefined // Do not enter LDAP_URI or LDAP_PASSWORD here, use env_vars
const devSsoBaseURL = devDefaults('https://login-r.referens.sys.kth.se')
const devLdapBase = devDefaults('OU=UG,DC=ref,DC=ug,DC=kth,DC=se')
const ldapOptions = {
base: getEnv('LDAP_BASE', devLdapBase),
filter: '(ugKthid=KTHID)',
filterReplaceHolder: 'KTHID',
userattrs: ['displayName', 'mail', 'ugUsername', 'memberOf', 'ugKthid'],
groupattrs: ['cn', 'objectCategory'],
testSearch: true, // TODO: Should this be an ENV setting?
timeout: typeConversion(getEnv('LDAP_TIMEOUT', null)),
reconnectTime: typeConversion(getEnv('LDAP_IDLE_RECONNECT_INTERVAL', null)),
reconnectOnIdle: getEnv('LDAP_IDLE_RECONNECT_INTERVAL', null) !== null,
connecttimeout: typeConversion(getEnv('LDAP_CONNECT_TIMEOUT', null)),
searchtimeout: typeConversion(getEnv('LDAP_SEARCH_TIMEOUT', null)),
}
Object.keys(ldapOptions).forEach(key => {
if (ldapOptions[key] === null) {
delete ldapOptions[key]
}
})
cas: {
ssoBaseURL: getEnv('CAS_SSO_URI', devSsoBaseURL),
},
ldap: unpackLDAPConfig('LDAP_URI', getEnv('LDAP_PASSWORD'), devLdap, ldapOptions),
Add
const devOidcIssuerURL = devDefaults('https://login.ref.ug.kth.se/adfs')
const devOidcConfigurationURL = devDefaults(`${devOidcIssuerURL}/.well-known/openid-configuration`)
const devOidcTokenSecret = devDefaults('tokenSecretString')
const prefixPath = devDefaults('/node') // Change this to your prefixPath!!!
const devOidcCallbackURL = devDefaults(`http://localhost:3000${prefixPath}/auth/login/callback`)
const devOidcCallbackSilentURL = devDefaults(`http://localhost:3000${prefixPath}/auth/silent/callback`)
const devOidcLogoutCallbackURL = devDefaults(`http://localhost:3000${prefixPath}/auth/logout/callback`)
Note: Change the prefixPath to fit your application!
oidc: {
configurationUrl: getEnv('OIDC_CONFIGURATION_URL', devDefaults(devOidcConfigurationURL)),
clientId: getEnv('OIDC_APPLICATION_ID', null),
clientSecret: getEnv('OIDC_CLIENT_SECRET', null),
tokenSecret: getEnv('OIDC_TOKEN_SECRET', devDefaults(devOidcTokenSecret)),
callbackLoginUrl: getEnv('OIDC_CALLBACK_URL', devDefaults(devOidcCallbackURL)),
callbackSilentLoginUrl: getEnv('OIDC_CALLBACK_SILENT_URL', devDefaults(devOidcCallbackSilentURL)),
callbackLogoutUrl: getEnv('OIDC_CALLBACK_LOGOUT_URL', devDefaults(devOidcLogoutCallbackURL)),
},
Remove
/* ******************************
* ******* AUTHENTICATION *******
* ******************************
*/
const passport = require('passport')
// const ldapClient = require('./adldapClient')
const {
authLoginHandler,
authCheckHandler,
logoutHandler,
pgtCallbackHandler,
serverLogin,
getServerGatewayLogin,
} = require('kth-node-passport-cas').routeHandlers({
casLoginUri: _addProxy('/login'),
casGatewayUri: _addProxy('/loginGateway'),
proxyPrefixPath: config.proxyPrefixPath.uri,
server,
})
const { redirectAuthenticatedUserHandler } = require('./authentication')
server.use(passport.initialize())
server.use(passport.session())
const authRoute = AppRouter()
authRoute.get('cas.login', _addProxy('/login'), authLoginHandler, redirectAuthenticatedUserHandler)
authRoute.get('cas.gateway', _addProxy('/loginGateway'), authCheckHandler, redirectAuthenticatedUserHandler)
authRoute.get('cas.logout', _addProxy('/logout'), logoutHandler)
// Optional pgtCallback (use config.cas.pgtUrl?)
authRoute.get('cas.pgtCallback', _addProxy('/pgtCallback'), pgtCallbackHandler)
server.use('/', authRoute.getRouter())
// Convenience methods that should really be removed
server.login = serverLogin
server.gatewayLogin = getServerGatewayLogin
Replace with this
/* ******************************
***** AUTHENTICATION - OIDC ****
****************************** */
const passport = require('passport')
server.use(passport.initialize())
server.use(passport.session())
passport.serializeUser((user, done) => {
if (user) {
done(null, user)
} else {
done()
}
})
passport.deserializeUser((user, done) => {
if (user) {
done(null, user)
} else {
done()
}
})
const { OpenIDConnect, hasGroup } = require('@kth/kth-node-passport-oidc')
const oidc = new OpenIDConnect(server, passport, {
...config.oidc,
callbackLoginRoute: _addProxy('/auth/login/callback'),
callbackLogoutRoute: _addProxy('/auth/logout/callback'),
callbackSilentLoginRoute: _addProxy('/auth/silent/callback'),
defaultRedirect: _addProxy(''),
failureRedirect: _addProxy(''),
// eslint-disable-next-line no-unused-vars
extendUser: (user, claims) => {
// eslint-disable-next-line no-param-reassign
user.isAdmin = hasGroup(config.auth.adminGroup, user)
},
})
// eslint-disable-next-line no-unused-vars
server.get(_addProxy('/login'), oidc.login, (req, res, next) => res.redirect(_addProxy('')))
// eslint-disable-next-line no-unused-vars
server.get(_addProxy('/logout'), oidc.logout)
If you don´t have the _addProxy
function:
const _addProxy = uri => `${config.proxyPrefixPath.uri}${uri}`
Change of routes examples
appRoute.get('node.index', _addProxy('/'), serverLogin, Sample.getIndex)
==>
appRoute.get('node.index', _addProxy('/'), oidc.login, Sample.getIndex)
appRoute.get('node.index', _addProxy('/'), getServerGatewayLogin('/'), Sample.getIndex)
==>
appRoute.get('node.index', _addProxy('/'), oidc.silentLogin, Sample.getIndex)
appRoute.get('node.index', _addProxy('/'), requireRole('isAdmin'), Sample.getIndex)
==>
appRoute.get('node.index', _addProxy('/'), oidc.requireRole('isAdmin'), Sample.getIndex)
Remove
const { requireRole } = require('./authentication')
First check in the redirectAuthenticatedUserHandler function and specifically the unpackLdapUser function.
If you have groups here, maybe "isAdmin" or "isSupport" and so on.
Copy this code.
And remove this file. Yupp, delete it!
If you copied code, go to server.js
and the to the extendUser
function. This is where this code belongs now, and may the existing admin role already works for you.
Delete this file if you have it
Maybe you have a monitor test on ldap? Then it's time to remove it.
Remove
const ldapClient = require('../adldapClient')
// Check LDAP
const ldapHealthUtil = registry.getUtility(IHealthCheck, 'kth-node-ldap')
subSystems.push(ldapHealthUtil.status(ldapClient, config.ldap))
Go through the code and look for places where you use req.session.authUser
and use req.user
instead.
Delete all with Ldap (unless you use it for more than authentication!)
In development mode you need 2 new things in your .env file.
OIDC_APPLICATION_ID=
OIDC_CLIENT_SECRET=
In your secrets file you will need:
OIDC_APPLICATION_ID=
OIDC_CLIENT_SECRET=
OIDC_TOKEN_SECRET=
OIDC_CONFIGURATION_URL=
OIDC_CALLBACK_URL=
OIDC_CALLBACK_SILENT_URL=
OIDC_CALLBACK_LOGOUT_URL=
Silent and logout is optional depending if you use it :-)