initial working discovery

if user is missing info, we will discover it automatically using well-known endpoints

mstrhakr committed Sep 4, 2022 at 15:18 UTC 7ec476ec4dab0c72d70572f82a1e7eb9b711b1c4
2 files changed +21 -12
meshcentral.js
+1 -1
@@ -3941,7 +3941,7 @@ function mainStart() {
3941 if ((typeof config.domains[i].authstrategies.github == 'object') && (typeof config.domains[i].authstrategies.github.clientid == 'string') && (typeof config.domains[i].authstrategies.github.clientsecret == 'string') && (passport.indexOf('passport-github2') == -1)) { passport.push('passport-github2'); }
3942 if ((typeof config.domains[i].authstrategies.reddit == 'object') && (typeof config.domains[i].authstrategies.reddit.clientid == 'string') && (typeof config.domains[i].authstrategies.reddit.clientsecret == 'string') && (passport.indexOf('passport-reddit') == -1)) { passport.push('passport-reddit'); }
3943 if ((typeof config.domains[i].authstrategies.azure == 'object') && (typeof config.domains[i].authstrategies.azure.clientid == 'string') && (typeof config.domains[i].authstrategies.azure.clientsecret == 'string') && (typeof config.domains[i].authstrategies.azure.tenantid == 'string') && (passport.indexOf('passport-azure-oauth2') == -1)) { passport.push('passport-azure-oauth2'); passport.push('jwt-simple'); }
3944 - if ((typeof config.domains[i].authstrategies.oidc == 'object') && (typeof config.domains[i].authstrategies.oidc.clientid == 'string') && (typeof config.domains[i].authstrategies.oidc.clientsecret == 'string') && (passport.indexOf('passport-openidconnect') == -1)) { passport.push('passport-openidconnect'); }
3944 + if ((typeof config.domains[i].authstrategies.oidc == 'object') && (typeof config.domains[i].authstrategies.oidc.clientid == 'string') && (typeof config.domains[i].authstrategies.oidc.clientsecret == 'string') && (typeof config.domains[i].authstrategies.oidc.issuer == 'string') && (passport.indexOf('passport-openidconnect') == -1)) { passport.push('passport-openidconnect'); passport.push('openid-client'); }
3945 if ((typeof config.domains[i].authstrategies.saml == 'object') || (typeof config.domains[i].authstrategies.jumpcloud == 'object')) { passport.push('passport-saml'); }
3946 }
3947 if (config.domains[i].sessionrecording != null) { sessionRecording = true; }
webserver.js
+20 -11
@@ -596,7 +596,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
596 // Indicate that this user has a image
597 if (userimage != null) { user.flags = 1; }
598
599 - // Synd the user with LDAP matching user groups
599 + // Sync the user with LDAP matching user groups
600 if (syncExternalUserGroups(domain, user, userMemberships, 'ldap') == true) { userChanged = true; }
601
602 obj.users[user._id] = user;
@@ -6421,8 +6421,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6421 }, handleStrategyLogin);
6422 }
6423
6424 - // Generic OpenID
6425 - if ((domain.authstrategies.authStrategyFlags & domainAuthStrategyConsts.openid) != 0) {
6424 + // Generic OpenID Connect
6425 + if ((domain.authstrategies.authStrategyFlags & domainAuthStrategyConsts.oidc) != 0) {
6426 obj.app.get(url + 'auth-oidc', function (req, res, next) {
6427 var domain = getDomain(req);
6428 if (domain.passport == null) { next(); return; }
@@ -6783,14 +6783,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6783 github: 3,
6784 reddit: 8,
6785 azure: 16,
6786 - openid: 32,
6786 + oidc: 32,
6787 saml: 64,
6788 intelSaml: 128,
6789 jumpCloudSaml: 256
6790 }
6791
6792 // Setup auth strategies for a domain
6793 - function setupDomainAuthStrategy(domain) {
6793 + async function setupDomainAuthStrategy(domain) {
6794 // Return the auth strategies that have been setup
6795 var authStrategyFlags = 0;
6796
@@ -6895,26 +6895,35 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6895
6896 // Generic OpenID Connect
6897 if ((typeof domain.authstrategies.oidc == 'object') && (typeof domain.authstrategies.oidc.clientid == 'string') && (typeof domain.authstrategies.oidc.clientsecret == 'string') && (typeof domain.authstrategies.oidc.issuer == 'string')) {
6898 + const OIDCStrategy = require('passport-openidconnect');
6899 var options = {
6900 issuer: domain.authstrategies.oidc.issuer,
6900 - authorizationURL: domain.authstrategies.oidc.authorizationurl,
6901 - tokenURL: domain.authstrategies.oidc.tokenurl,
6902 - userInfoURL: domain.authstrategies.oidc.userinfourl,
6901 clientID: domain.authstrategies.oidc.clientid,
6902 clientSecret: domain.authstrategies.oidc.clientsecret,
6903 scope: ['profile email'],
6904 };
6907 - var OIDCStrategy = require('passport-openidconnect');
6905 + if ((typeof domain.authstrategies.oidc.authorizationurl != 'string') || (typeof domain.authstrategies.oidc.tokenurl != 'string') || (typeof domain.authstrategies.oidc.userinfourl != 'string')) {
6906 + const Issuer = require('openid-client').Issuer;
6907 + parent.debug('web', 'Attempting to discover well known endpoints for ' + options.issuer);
6908 + var issuer = await Issuer.discover(options.issuer);
6909 + parent.debug('web', `Discovered from ${issuer.metadata.issuer}:
6910 + authorization_endpoint - ${issuer.metadata.authorization_endpoint}
6911 + token_endpoint - ${issuer.metadata.token_endpoint}
6912 + userinfo_endpoint - ${issuer.metadata.userinfo_endpoint}`);
6913 + }
6914 + if (typeof domain.authstrategies.oidc.authorizationurl == 'string') { options.authorizationURL = domain.authstrategies.oidc.authorizationurl; } else { options.authorizationURL = issuer.metadata.authorization_endpoint; }
6915 + if (typeof domain.authstrategies.oidc.tokenurl == 'string') { options.tokenURL = domain.authstrategies.oidc.tokenurl; } else { options.tokenURL = issuer.metadata.token_endpoint; }
6916 + if (typeof domain.authstrategies.oidc.userinfourl == 'string') { options.userInfoURL = domain.authstrategies.oidc.userinfourl; } else { options.userInfoURL = issuer.metadata.userinfo_endpoint; }
6917 if (typeof domain.authstrategies.oidc.callbackurl == 'string') { options.callbackURL = domain.authstrategies.oidc.callbackurl; } else { options.callbackURL = url + 'oidc-callback'; }
6918 parent.debug('web', 'Adding Generic OIDC SSO with options: ' + JSON.stringify(options));
6919 passport.use('oidc-' + domain.id, new OIDCStrategy.Strategy(options,
6920 function verify(issuer, profile, verified) {
6921 var user = { sid: '~oidc:' + profile.id, name: profile.displayName, email: profile.email, strategy: 'oidc' };
6913 - parent.debug('AUTH', 'OIDC: Configured user: ' + JSON.stringify(user));
6922 + parent.debug('AUTH', `OIDC: Configured user: ${JSON.stringify(user)} using ${issuer}`);
6923 return verified(null, user);
6924 }
6925 ));
6917 - authStrategyFlags |= domainAuthStrategyConsts.openid;
6926 + authStrategyFlags |= domainAuthStrategyConsts.oidc;
6927 }
6928
6929 // Generic SAML