Single Sign On
📘 Prerequisites
You will need PUBLIC_KEY for SSO.
For Single Sign On (SSO) to work properly when user logins, website needs to encrypt user information with pre-shared PUBLIC_KEY and save that in cookie under main domain.
Artisio Webapp is integrated on the website, just like it is part of the website. That's why it has access on all cookies. Artisio Webapp will read that cookie and pass down to the Artisio servers and users will be authenticated.
What to encrypt?
The customers on which SSO should work must be also pushed to Artisio AMS.
Website must take authenticated customers UUID (Provided by Artisio) and authentication expire date timestamp (in seconds) and encrypt them as JSON.
{"uuid": "63239aab-e74a-4e2d-a149-e99add0cfff0", "expire_date": "2022-10-28 18:18:38 +00:00"}
🚧 Expire Date must be one of the following formats
2022-09-29 02:41:36.123456 +00:00
2022-09-29 02:41:36.123456
2022-09-29 02:41:36 +00:00
2022-09-29 02:41:36
How to encrypt?
The JSON must be encrypted with pre-shared PUBLIC_KEY. Your Artisio account manager should provide PUBLIC_KEY. Good practice is to set the expire date inside the JSON the same value whatever is set for user's authentication session expire date.
Where to save?
Encrypted string should be saved in root domain's cookie under key artisio_timed_sso
(this key will become configurable in the future). Website developer can decide what should be the cookie expiration date.
TIP
The values saved in cookie must be base64 encoded
Full Example
# Install package cryptography==35.0.0
import json
import base64
from datetime import datetime, timedelta
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes, serialization
d = datetime.today() + timedelta(hours=12) # Example: 12 hours from now
tm = d.strftime('%Y-%m-%d %H:%M:%S') + ' +00:00' # Assuming the date is in UTC timezone
data = json.dumps({"uuid": "63239aab-e74a-4e2d-a149-e99add0cfff0", "expire_date": tm})
with open('/path/to/public/key', "rb") as key_file:
public_key = serialization.load_pem_public_key(key_file.read(), backend=default_backend())
return base64.b64encode(public_key.encrypt(
data.encode(),
padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)
)).decode()
# Save in cookie under artisio_timed_sso key
// Install package phpseclib/phpseclib:^3.0
require __DIR__ . '/vendor/autoload.php';
$ssoKey = file_get_contents("/path/to/public/key");
$key = \phpseclib3\Crypt\PublicKeyLoader::load($ssoKey)->withHash('sha256')->withMGFHash('sha256');
$dd = new \DateTime();
$dd->setTimezone(new DateTimeZone('UTC'));
$dd->modify('+12 hours'); // Example: 12 hours from now.
$expiration = $dd->format('Y-m-d H:i:s P');
$json = json_encode(['uuid' => '63239aab-e74a-4e2d-a149-e99add0cfff0', 'expire_date' => $expiration]);
$cookie_token = base64_encode($key->encrypt($json));
// Save in cookie under artisio_timed_sso key
setcookie('artisio_timed_sso', $cookie_token), $expiration);
let crypto = require("crypto");
let path = require("path");
let fs = require("fs");
let encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey) {
let absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey);
let publicKey = fs.readFileSync(absolutePath, "utf8");
let encrypted = crypto.publicEncrypt({
oaepHash: "sha256",
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
key: publicKey,
}, Buffer.from(toEncrypt));
return encrypted.toString("base64");
};
const d = new Date();
d.setTime(d.getTime() + 12 * 60 * 60 * 1000); // Add 12 hours from now
const tm = d.toISOString().replace('T', ' ').replace(/\.\d{3}Z/, '');
let data = JSON.stringify({
"uuid": "ARTISIO_CUSTOMER_UUID",
"expire_date": tm,
})
res.send(encryptStringWithRsaPublicKey(data, '/pah/to/public_key'))