mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-22 22:17:31 +03:00
Merge pull request #3856 from mstrhakr/generic-oidc
Feature Request: Generic OIDC
This commit is contained in:
commit
a8992f6a09
@ -1069,6 +1069,21 @@
|
||||
"logouturl": {"type": "string", "format": "uri", "description": "Then set, the user will be redirected to this URL when hitting the logout link."}
|
||||
},
|
||||
"required": [ "entityid", "idpurl", "cert" ]
|
||||
},
|
||||
"oidc": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"authorizationURL": { "type": "string", "format": "uri", "description": "If set, this will be used as the authorization URL. (If set tokenURL and userInfoURL need set also)" },
|
||||
"callbackURL": { "type": "string", "format": "uri", "description": "Required, this is the URL that your SSO provider sends auth approval to." },
|
||||
"clientid": { "type": "string" },
|
||||
"clientsecret": { "type": "string" },
|
||||
"issuer": { "type": "string", "format": "uri", "description": "Full URL of SSO portal" },
|
||||
"tokenURL": { "type": "string", "format": "uri", "description": "If set, this will be used as the token URL. (If set authorizationURL and userInfoURL need set also)" },
|
||||
"userInfoURL": { "type": "string", "format": "uri", "description": "If set, this will be used as the user info URL. (If set authorizationURL and tokenURL need set also)" },
|
||||
"logouturl": { "type": "string", "format": "uri", "description": "Then set, the user will be redirected to this URL when hitting the logout link." },
|
||||
"newAccounts": { "type": "boolean", "default": true }
|
||||
},
|
||||
"required": [ "issuer", "clientid", "clientsecret", "callbackURL" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3495,6 +3495,7 @@ function mainStart() {
|
||||
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'); }
|
||||
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'); }
|
||||
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'); }
|
||||
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('@mstrhakr/passport-generic-oidc') == -1)) { passport.push('@mstrhakr/passport-generic-oidc'); }
|
||||
if ((typeof config.domains[i].authstrategies.saml == 'object') || (typeof config.domains[i].authstrategies.jumpcloud == 'object')) { passport.push('passport-saml'); }
|
||||
}
|
||||
if (config.domains[i].sessionrecording != null) { sessionRecording = true; }
|
||||
|
BIN
public/images/Login/oidc32.png
Normal file
BIN
public/images/Login/oidc32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
public/images/Login/oidc64.png
Normal file
BIN
public/images/Login/oidc64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
@ -138,7 +138,7 @@
|
||||
"footer": "Default page footer",
|
||||
"newAccounts": false
|
||||
},
|
||||
"_domains": {
|
||||
"domains": {
|
||||
"": {
|
||||
"_siteStyle": 2,
|
||||
"title": "MyServer",
|
||||
@ -250,21 +250,21 @@
|
||||
"files": "{0} started a remote files session."
|
||||
},
|
||||
"_agentCustomization": {
|
||||
"displayName": "Compagny® Product™",
|
||||
"description": "Compagny® Product™ agent for remote monitoring, management and assistance.",
|
||||
"companyName": "Compagny",
|
||||
"serviceName": "compagnyagent",
|
||||
"displayName": "Company® Product™",
|
||||
"description": "Company® Product™ agent for remote monitoring, management and assistance.",
|
||||
"companyName": "Company®",
|
||||
"serviceName": "companyagent",
|
||||
"image": "agent-logo.png",
|
||||
"fileName": "compagnyagent"
|
||||
},
|
||||
"_assistantCustomization": {
|
||||
"title": "Compagny® Product™",
|
||||
"title": "Company® Product™",
|
||||
"image": "assistant-logo.png",
|
||||
"fileName": "compagny"
|
||||
},
|
||||
"_androidCustomization": {
|
||||
"title": "Compagny® Product™",
|
||||
"subtitle": "Product Subtitle™",
|
||||
"title": "Company® Product™",
|
||||
"subtitle": "Product Subtitle™",
|
||||
"image": "assistant-logo.png"
|
||||
},
|
||||
"_userAllowedIP": "127.0.0.1,192.168.1.0/24",
|
||||
@ -407,6 +407,17 @@
|
||||
"entityid": "meshcentral",
|
||||
"idpurl": "https://server/saml2",
|
||||
"cert": "saml.pem"
|
||||
},
|
||||
"oidc": {
|
||||
"authorizationURL": "https://sso.server.com/api/oidc/authorization",
|
||||
"callbackURL": "https://mesh.server.com/oidc-callback",
|
||||
"clientid": "00000000-0000-0000-0000-000000000000",
|
||||
"clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"issuer": "https://sso.server.com",
|
||||
"tokenURL": "https://sso.server.com/api/oidc/token",
|
||||
"userInfoURL": "https://sso.server.com/api/oidc/userinfo",
|
||||
"logoutURL": "https://sso.server.com/logout",
|
||||
"newAccounts": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -14852,6 +14852,7 @@
|
||||
else if (shortuserid.startsWith('~github:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/github64.png'; }
|
||||
else if (shortuserid.startsWith('~reddit:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/reddit64.png'; }
|
||||
else if (shortuserid.startsWith('~azure:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/azure64.png'; }
|
||||
else if (shortuserid.startsWith('~oidc:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/oidc64.png'; }
|
||||
else if (shortuserid.startsWith('~jumpcloud:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/jumpcloud64.png'; }
|
||||
else if (shortuserid.startsWith('~intel:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/intel64.png'; }
|
||||
else if (shortuserid.startsWith('~:')) { QV('p30userAuthServiceLogo', true); Q('p30userAuthServiceLogo').src = 'images/login/generic64.png'; }
|
||||
|
@ -90,6 +90,7 @@
|
||||
<a id="auth-github" href="auth-github" style="display:none"><img src="images/login/github32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using GitHub" /></a>
|
||||
<a id="auth-reddit" href="auth-reddit" style="display:none"><img src="images/login/reddit32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Reddit" /></a>
|
||||
<a id="auth-azure" href="auth-azure" style="display:none"><img src="images/login/azure32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Azure" /></a>
|
||||
<a id="auth-oidc" href="auth-oidc" style="display:none"><img src="images/login/oidc32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using OpenID Connect" /></a>
|
||||
<a id="auth-jumpcloud" href="auth-jumpcloud" style="display:none"><img src="images/login/jumpcloud32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using JumpCloud" /></a>
|
||||
<a id="auth-intel" href="auth-intel" style="display:none"><img src="images/login/intel32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Intel" /></a>
|
||||
<a id="auth-saml" href="auth-saml" style="display:none"><img src="images/login/generic32.png" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Single Sign-in" /></a>
|
||||
@ -387,6 +388,7 @@
|
||||
if (authStrategies.indexOf('github') >= 0) { QV('auth-github', true); }
|
||||
if (authStrategies.indexOf('reddit') >= 0) { QV('auth-reddit', true); }
|
||||
if (authStrategies.indexOf('azure') >= 0) { QV('auth-azure', true); }
|
||||
if (authStrategies.indexOf('oidc') >= 0) { QV('auth-oidc', true); }
|
||||
if (authStrategies.indexOf('jumpcloud') >= 0) { QV('auth-jumpcloud', true); }
|
||||
if (authStrategies.indexOf('intel') >= 0) { QV('auth-intel', true); }
|
||||
if (authStrategies.indexOf('saml') >= 0) { QV('auth-saml', true); }
|
||||
|
@ -82,6 +82,7 @@
|
||||
<a id="auth-github" href="auth-github" style="display:none"><img src="images/login/github32.png" srcset="images/login/github64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using GitHub" /></a>
|
||||
<a id="auth-reddit" href="auth-reddit" style="display:none"><img src="images/login/reddit32.png" srcset="images/login/reddit64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Reddit" /></a>
|
||||
<a id="auth-azure" href="auth-azure" style="display:none"><img src="images/login/azure32.png" srcset="images/login/azure64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Azure" /></a>
|
||||
<a id="auth-oidc" href="auth-oidc" style="display:none"><img src="images/login/oidc32.png" srcset="images/login/oidc64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using OpenID Connect" /></a>
|
||||
<a id="auth-jumpcloud" href="auth-jumpcloud" style="display:none"><img src="images/login/jumpcloud32.png" srcset="images/login/jumpcloud64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using JumpCloud" /></a>
|
||||
<a id="auth-intel" href="auth-intel" style="display:none"><img src="images/login/intel32.png" srcset="images/login/intel64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Intel" /></a>
|
||||
<a id="auth-saml" href="auth-saml" style="display:none"><img src="images/login/generic32.png" srcset="images/login/generic64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Single Sign-in" /></a>
|
||||
@ -408,6 +409,7 @@
|
||||
if (authStrategies.indexOf('github') >= 0) { QV('auth-github', true); }
|
||||
if (authStrategies.indexOf('reddit') >= 0) { QV('auth-reddit', true); }
|
||||
if (authStrategies.indexOf('azure') >= 0) { QV('auth-azure', true); }
|
||||
if (authStrategies.indexOf('oidc') >= 0) { QV('auth-oidc', true); }
|
||||
if (authStrategies.indexOf('jumpcloud') >= 0) { QV('auth-jumpcloud', true); }
|
||||
if (authStrategies.indexOf('intel') >= 0) { QV('auth-intel', true); }
|
||||
if (authStrategies.indexOf('saml') >= 0) { QV('auth-saml', true); }
|
||||
|
@ -104,6 +104,7 @@
|
||||
<a id="auth-github" href="auth-github" style="display:none"><img src="images/login/github32.png" srcset="images/login/github64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using GitHub" /></a>
|
||||
<a id="auth-reddit" href="auth-reddit" style="display:none"><img src="images/login/reddit32.png" srcset="images/login/reddit64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Reddit" /></a>
|
||||
<a id="auth-azure" href="auth-azure" style="display:none"><img src="images/login/azure32.png" srcset="images/login/azure64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Azure" /></a>
|
||||
<a id="auth-oidc" href="auth-oidc" style="display:none"><img src="images/login/oidc32.png" srcset="images/login/oidc64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using OpenID Connect" /></a>
|
||||
<a id="auth-jumpcloud" href="auth-jumpcloud" style="display:none"><img src="images/login/jumpcloud32.png" srcset="images/login/jumpcloud64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using JumpCloud" /></a>
|
||||
<a id="auth-intel" href="auth-intel" style="display:none"><img src="images/login/intel32.png" srcset="images/login/intel64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Sign-in using Intel" /></a>
|
||||
<a id="auth-saml" href="auth-saml" style="display:none"><img src="images/login/generic32.png" srcset="images/login/generic64.png 2x" loading="lazy" width="32" height="32" style="margin-left:3px;margin-right:3px;border-radius:3px;box-shadow:2px 2px 5px black;cursor:pointer" title="Single Sign-in" /></a>
|
||||
@ -473,6 +474,7 @@
|
||||
if (authStrategies.indexOf('github') >= 0) { QV('auth-github', true); }
|
||||
if (authStrategies.indexOf('reddit') >= 0) { QV('auth-reddit', true); }
|
||||
if (authStrategies.indexOf('azure') >= 0) { QV('auth-azure', true); }
|
||||
if (authStrategies.indexOf('oidc') >= 0) { QV('auth-oidc', true); }
|
||||
if (authStrategies.indexOf('jumpcloud') >= 0) { QV('auth-jumpcloud', true); }
|
||||
if (authStrategies.indexOf('intel') >= 0) { QV('auth-intel', true); }
|
||||
if (authStrategies.indexOf('saml') >= 0) { QV('auth-saml', true); }
|
||||
|
31
webserver.js
31
webserver.js
@ -783,6 +783,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||
if (u.startsWith('~github:') && (domain.authstrategies.github != null) && (typeof domain.authstrategies.github.logouturl == 'string')) { res.redirect(domain.authstrategies.github.logouturl); return; }
|
||||
if (u.startsWith('~reddit:') && (domain.authstrategies.reddit != null) && (typeof domain.authstrategies.reddit.logouturl == 'string')) { res.redirect(domain.authstrategies.reddit.logouturl); return; }
|
||||
if (u.startsWith('~azure:') && (domain.authstrategies.azure != null) && (typeof domain.authstrategies.azure.logouturl == 'string')) { res.redirect(domain.authstrategies.azure.logouturl); return; }
|
||||
if (u.startsWith('~oidc:') && (domain.authstrategies.oidc != null) && (typeof domain.authstrategies.oidc.logouturl == 'string')) { res.redirect(domain.authstrategies.oidc.logouturl); return; }
|
||||
if (u.startsWith('~jumpcloud:') && (domain.authstrategies.jumpcloud != null) && (typeof domain.authstrategies.jumpcloud.logouturl == 'string')) { res.redirect(domain.authstrategies.jumpcloud.logouturl); return; }
|
||||
if (u.startsWith('~saml:') && (domain.authstrategies.saml != null) && (typeof domain.authstrategies.saml.logouturl == 'string')) { res.redirect(domain.authstrategies.saml.logouturl); return; }
|
||||
if (u.startsWith('~intel:') && (domain.authstrategies.intel != null) && (typeof domain.authstrategies.intel.logouturl == 'string')) { res.redirect(domain.authstrategies.intel.logouturl); return; }
|
||||
@ -3008,6 +3009,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||
if (typeof domain.authstrategies.github == 'object') { authStrategies.push('github'); }
|
||||
if (typeof domain.authstrategies.reddit == 'object') { authStrategies.push('reddit'); }
|
||||
if (typeof domain.authstrategies.azure == 'object') { authStrategies.push('azure'); }
|
||||
if (typeof domain.authstrategies.oidc == 'object') { authStrategies.push('oidc'); }
|
||||
if (typeof domain.authstrategies.intel == 'object') { authStrategies.push('intel'); }
|
||||
if (typeof domain.authstrategies.jumpcloud == 'object') { authStrategies.push('jumpcloud'); }
|
||||
if (typeof domain.authstrategies.saml == 'object') { authStrategies.push('saml'); }
|
||||
@ -6239,6 +6241,35 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||
}, handleStrategyLogin);
|
||||
}
|
||||
|
||||
// Generic OpenID Connect
|
||||
if ((typeof domain.authstrategies.oidc == 'object') && (typeof domain.authstrategies.oidc.clientid == 'string') && (typeof domain.authstrategies.oidc.clientsecret == 'string') && (typeof domain.authstrategies.oidc.issuer == 'string')) {
|
||||
var options = {
|
||||
authorizationURL: domain.authstrategies.oidc.authorizationurl,
|
||||
callbackURL: domain.authstrategies.oidc.callbackurl,
|
||||
clientID: domain.authstrategies.oidc.clientid,
|
||||
clientSecret: domain.authstrategies.oidc.clientsecret,
|
||||
issuer: domain.authstrategies.oidc.issuer,
|
||||
tokenURL: domain.authstrategies.oidc.tokenurl,
|
||||
userInfoURL: domain.authstrategies.oidc.userinfourl,
|
||||
scope: [ 'openid profile email' ],
|
||||
responseMode: 'form_post' ,
|
||||
state: true
|
||||
};
|
||||
const OIDCStrategy = require('@mstrhakr/passport-generic-oidc');
|
||||
if (typeof domain.authstrategies.oidc.callbackurl == 'string') { options.callbackURL = domain.authstrategies.oidc.callbackurl; } else { options.callbackURL = url + 'oidc-callback'; }
|
||||
parent.debug('web', 'Adding Generic OIDC SSO with options: ' + JSON.stringify(options));
|
||||
passport.use('openidconnect', new OIDCStrategy.Strategy(options,
|
||||
function verify( iss, sub, profile, cb ) {
|
||||
var user = { sid: '~oidc:' + profile.id, name: profile.displayName, email: profile.email, strategy: 'oidc' };
|
||||
parent.debug('AUTH', 'OIDC: Configured user: ' + JSON.stringify(user));
|
||||
return cb(null, user);
|
||||
}
|
||||
));
|
||||
obj.app.get(url + 'auth-oidc', domain.passport.authenticate('openidconnect'));
|
||||
obj.app.get(url + 'oidc-callback', domain.passport.authenticate('openidconnect', { failureRedirect: '/login?failed-auth-attempt', failureFlash: true }), handleStrategyLogin);
|
||||
}
|
||||
|
||||
|
||||
// Generic SAML
|
||||
if (typeof domain.authstrategies.saml == 'object') {
|
||||
if ((typeof domain.authstrategies.saml.cert != 'string') || (typeof domain.authstrategies.saml.idpurl != 'string')) {
|
||||
|
Loading…
Reference in New Issue
Block a user