Need Help? We are right here!
Thanks for your inquiry.
If you dont hear from us within 24 hours, please feel free to send a follow up email to info@xecurify.com
Search Results:
×GhostJS SSO (Single Sign On) allows your users to log into GhostJS with your Identity Provider credentials. IT admins can easily manage user access activities and grant or revoke SSO access to GhostJS application. This is done using JSON Web Token (JWT) tokens and it can be easily integrated with GhostJS built in any framework or language. The following document contains instructions on how to connect your GhostJS application to the miniOrange application using a JWT token. This allows you to add SSO, 2FA, or MFA to your GhostJS application in very easy steps
In case you need our help with the integration or setup proces, feel free to reach out idpsupport@xecurify.com
npm install --save base64url jsrsasign jssha utf8
{{#if @site.members_enabled}} {{#unless @member}} <a class="gh-head-button" href= '<YOUR SSO URL>', //"https://loginxyz.xecurify.com/moas/broker/login/jwt/273903?client_id=vk rLa5jmY0kChu4a&redirect_uri=http://localhost:2368/members/?action=signin", >MiniOrange SSO</a> {{/if}}
const JWTBuilder = require("./jwt-connector/JWTBuilder"); const cert = "< PLACE YOUR CERTIFICATE STRING HERE >"; var verified = false; async function getMemberDataFromSSOToken(jwt) { if(jwt) { //Initialize the JWT var jwtBuilder = new JWTBuilder.default; jwtBuilder.parseJwt(jwt); // set the secret that was shared by your IDP jwtBuilder.setSecret(cert); try { //Compare the hashed jwt with the one received verified = jwtBuilder.verifyJwt(); } catch (error) { console.error(error); } if (verified) { // once you find the JWT is verified, you can go ahead and get the data from JWT let user = jwtBuilder.getPayload(); if (!user) { return null; } let email = user["email"]; let name = user["first_name"] + user["last_name"]; let labels = []; let newsletters = []; const member = await getMemberIdentityData(email); if(member) { await MemberLoginEvent.add({ member_id: member.id }); return member; } const newMember = await users.create({ name, email, labels, newsletters, }); await MemberLoginEvent.add({ member_id: newMember.id }); return getMemberIdentityData(email); } } return null; }
return { middleware, getMemberDataFromMagicLinkToken, getMemberDataFromSSOToken, getMemberIdentityToken, ... };
/** * @method _getMemberDataFromSSOToken * * @param {JWT} token * * @returns {Promise} member */ async _getMemberDataFromSSOToken(token) { const api = await this._getMembersApi(); return api.getMemberDataFromSSOToken(token); } /** * @method exchangeSSOTokenForSession * @param {Request} req * @param {Response} res * * @returns {Promise } The member the session was created for */ async exchangeSSOTokenForSession(req, res) { if (!req.url) { return Promise.reject(new BadRequestError({ message: 'Expected token param containing JWT' })); } const {query} = parseUrl(req.url, true); if (!query || !query.id_token) { return Promise.reject(new BadRequestError({ message: 'Expected token param containing JWT' })); } const token = Array.isArray(query.id_token) ? query.id_token[0] : query.id_token; const member = await this._getMemberDataFromSSOToken(token); // perform and store geoip lookup for members when they log in if (!member.geolocation) { try { await this._setMemberGeolocationFromIp(member.email, req.ip); } catch (err) { // no-op, we don't want to stop anything working due to // geolocation lookup failing debug(`Geolocation lookup failed: ${err.message}`); } } this._setSessionCookie(req, res, member.email); return member; }
const createSessionFromSSOLink = async function (req, res, next) { if (!req.url.includes("id_token=")) { return next(); } // req.query is a plain object, copy it to a URLSearchParams object so we can call toString() const searchParams = new URLSearchParams(""); Object.keys(req.query).forEach((param) => { // don't copy the id_token param if (param !== "id_token") { searchParams.set(param, req.query[param]); } }); try { const member = await membersService.ssr.exchangeSSOTokenForSession(req,res); const subscriptions = (member && member.subscriptions) || []; const action = req.query.action; if ( action === "signup" || action === "signup-paid" || action === "subscribe" ) { let customRedirect = ""; const mostRecentActiveSubscription = subscriptions .sort((a, b) => { const aStartDate = new Date(a.start_date); const bStartDate = new Date(b.start_date); return bStartDate.valueOf() - aStartDate.valueOf(); }) .find((sub) => ["active", "trialing"].includes(sub.status)); if (mostRecentActiveSubscription) { customRedirect = mostRecentActiveSubscription.tier.welcome_page_url; } else { const freeTier = await models.Product.findOne({ type: "free" }); customRedirect = (freeTier && freeTier.get("welcome_page_url")) || ""; } if (customRedirect && customRedirect !== "/") { const baseUrl = urlUtils.getSiteUrl(); const ensureEndsWith = (string, endsWith) => string.endsWith(endsWith) ? string : string + endsWith; const removeLeadingSlash = (string) => string.replace(/^\//, ""); const redirectUrl = new URL( removeLeadingSlash(ensureEndsWith(customRedirect, "/")), ensureEndsWith(baseUrl, "/") ); return res.redirect(redirectUrl.href); } } // Do a standard 302 redirect to the homepage, with success=true searchParams.set("success", true); res.redirect(`${urlUtils.getSubdir()}/?${searchParams.toString()}`); } catch (err) { logging.warn(err.message); // Do a standard 302 redirect to the homepage, with success=false searchParams.set("success", false); res.redirect(`${urlUtils.getSubdir()}/?${searchParams.toString()}`); } };
module.exports = { loadMemberSession, createSessionFromMagicLink, createSessionFromSSOLink, ... };
membersApp.use(middleware.createSessionFromSSOLink);
Test SSO login to your GhostJS account with miniOrange IdP:
Contact us or email us at idpsupport@xecurify.com and we'll help you setting it up in no time.
miniOrange provides user authentication from various external sources, which can be Directories (like ADFS, Microsoft Active Directory, Azure AD, OpenLDAP, Google, AWS Cognito etc), Identity Providers (like Okta, Shibboleth, Ping, OneLogin, KeyCloak), Databases (like MySQL, Maria DB, PostgreSQL) and many more. You can configure your existing directory/user store or add users in miniOrange.
1. Create User in miniOrange
2. Bulk Upload Users in miniOrange via Uploading CSV File.
Here's the list of the attributes and what it does when we enable it. You can enable/disable accordingly.
Attribute | Description |
---|---|
Activate LDAP | All user authentications will be done with LDAP credentials if you Activate it |
Sync users in miniOrange | Users will be created in miniOrange after authentication with LDAP |
Fallback Authentication | If LDAP credentials fail then user will be authenticated through miniOrange |
Allow users to change password | This allows your users to change their password. It updates the new credentials in your LDAP server |
Enable administrator login | On enabling this, your miniOrange Administrator login authenticates using your LDAP server |
Show IdP to users | If you enable this option, this IdP will be visible to users |
Send Configured Attributes | If you enable this option, then only the attributes configured below will be sent in attributes at the time of login |
Refer our guide to setup LDAPS on windows server.
miniOrange integrates with various external user sources such as directories, identity providers, and etc.
Contact us or email us at idpsupport@xecurify.com and we'll help you setting it up in no time.
If you want to ensure that all sessions (SP and IDP) for a user are properly closed, you can configure Single Logout with the steps below.
A. Configure miniOrange with IdP SLO endpoint:
B. Configure IdP with miniOrange SLO endpoint:
https://login.xecurify.in/moas/broker/login/saml_logout/<your-customer-id>
C. Configure your JWT application with SLO endpoint:
https://login.xecurify.in/moas/broker/login/jwt/logout/<your-customer-id>?redirect_uri=<redirect-url>
your-customer-id | You have to add your miniOragne account customer ID here. |
redirect-url | This should be replaced with the logout URL of your JWT application. |
Our Other Identity & Access Management Products