Single Sign-on Integration

Definitions

Technical information

Enabling and disabling SSO

SSO authorization 

SSO LogOut Description

Schema

Steps

Implementation

Server-side implementation (PHP)

Client-side implementation

Initialization

Encryption

Decryption

SolidOpinion JavaScript API


Definitions

AES  – The Advanced Encryption Standard (AES), also known as Rijndael (its original name), is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001. The algorithm described by AES is a symmetric-key algorithm, meaning the same key is used for both encrypting and decrypting the data.

Automatic SSO – allows users to be signed in/signed up in SolidOpinion automatically using their account on your website.

Encryption key – a secret key (32 chars), used both to encrypt and decrypt data in AES algorithm. DO NOT SHARE THIS KEY WITH ANYONE!

Public key – a key, used to verify the signature, is a part of the asymmetric-key signing algorithm. The signing key is a secret key, used to sign the signature, is a part of the asymmetric-key signing algorithm. DO NOT SHARE THIS KEY WITH ANYONE!

Single sign-on (SSO) – is a property of access control of multiple related, but independent software systems. With this property a user logs in once and gains access to all systems without being prompted to log in again to each of them.


Technical Information

SolidOpinion requires a user email, as a unique identifier within the system, to sign in/sign up a user. In case your system doesn’t require a unique email, SolidOpinion will generate it based on other unique information (id, username, uid, etc).

Make sure the time on your server is synchronized with NTP servers, since timestamp is involved in data validation process. Do not send the same encrypted data more than once, as this situation can be considered as “a repeat attack”, - only first message will be processed. 


Enabling and disabling SSO
 
To enable SolidOpinion SSO for your website, please log in to your SolidOpinion account to adjust the site settings. Go to the “Your sites” tab and find the site, for which SSO should be enabled. Click on the small arrow near the “Settings” button and select the “Filters” option from the dropdown list. Put a tick in the “Enable Single Sign On” check box to generate new crypto keys and enable SSO. You will see generated keys after operation is complete. To apply the changes click the “Save Changes” button.

To disable SSO just remove the tick from the “Enable Single Sign On” check box and click the “Save Changes” button to apply the changes. Be careful, if any of your secret keys (encryption or signing in/up) is suspected to be compromised, immediately regenerate all SSO keys. To do this disable and enable SSO back again. Make sure to change the corresponding keys on your backend. 

SSO authorization 

Authorization of SSO is fulfilled in such a way: $SO.SSOLogIn (YOUR_ECRYPTED_KEY); Deferred SSO allows us to authorize users by the SSO encrypted key in JavaScript. The key is the same as you have put to the SolidOpinion data-encrypted div container. It should be used on sites that authorize users without "reloading" page content for synchronizing site authorization with SolidOpinion. 

SSO LogOut Description

SSO LogOut is fulfilled in such a way: LogOut of the User will become a part of public SolidOpinion api (now in beta). After the widget has loaded you will have "$SO object" that should have some methods for widget controlling. By calling the method "$SO.LogOut();" the authorization will be removed from the User. 

Schema




Steps

1) Contact SolidOpinion and provide us with information about your user data structure and your HTTP origins, so we can add the CORS header for them
2) Enable SSO for your website in the settings as described in the “Enabling and disabling SSO” section
3) Copy generated keys and save them on your Site Backend. PLEASE DO NOT STORE KEYS ON THE CLIENT SIDE (i.e. in JS)
4) User logs in on your site’s webpage, sending credentials to your site backend
5) In case credentials are correct, user information is packed into dictionary/associative array (payload), so that keys are names of fields and values are corresponding values
6) If a user is authenticated in your system - Payload is encrypted with the library provided by SolidOpinion and sends back encrypted data to the webpage; If a user is not authenticated - just pass an empty string into the data-encrypted attribute
7) The webpage loads the SolidOpinion widget and passes encrypted data into the “data-encrypted” attribute
8) The widget sends encrypted data to SolidOpinion API where data is decrypted
9) If decryption process succeeded and user payload was extracted, SolidOpinion checks whether a user already exists in the system. If not, a user is signed up with the provided credentials. After that the user is automatically signed in
10) The widget receives the API response and logs the user in 
11) Follow this link to download the file library soauth.php

Implementation

Server-side implementation (PHP)

require(YOUR_PATH_TO_LIB . ‘/soauth.php’); 
use SolidOpinion\SOAuth;

define("ENCRYPTION_KEY","<paste_your_encryption_key_here>"); 
define("SIGNING_KEY","<paste_your_signing_key_here>"); 
define("PUBLIC_KEY","<paste_your_public_key_here>"); 
// your payload structure 
$payload = [ 
'user' => $user['name'], 'email' => $user['email'], 'avatar' => $user['avatar_url'] 
]; 
$soAuth = new SOAuth(ENCRYPTION_KEY, SIGNING_KEY, PUBLIC_KEY); 
$data = $soAuth->encrypt($payload);
Client-side implementation
Download soauth.php
<div class="so_comments" data-
sitename="YOUR_SITE_NAME_ID"  data-encrypted='<?php echo($data); ?

>'></div> 
<script src="//api.solidopinion.com/widget/embed.js" async="async"></script>
Initialization
/**
*Constructor initialized with 3 keys
*@param string $encKey encryption key
*@param string $signKey signing key
*@param  string $pubKey public key
*@throws SOException
*/
public function__construct($encKey,$signKey,$pubKey)
{
if (!extension_loaded('openssl')){
throw newSOException('OpenSSLlib is not loaded');
}
if(SOUtils::strlen($encKey)!=SOUtils::keylen()){
throw new SOException('Invalid encryption key length');
}
$this->_encKey = $encKey;
$this->_signKey = $signKey;
$this->_pubKey = $pubKey;
//Generate initialization vector
$this->_iv = openssl_random_pseudo_bytes(SOUtils::keylen()/2,$strong);
if(!$strong){
throw new SOException('OpenSSL version is out of date');
}
//keylen equals 32
$bitLength = 8 * SOUtils::keylen();
$this->_mode ='aes-'.$bitLength.'-cbc';
$this->_option =defined('OPENSSL_RAW_DATA')? OPENSSL_RAW_DATA:      
true;
}
Encryption
/**
* Encrypts data
* @param array|mixed $payload array contains user data
* @return string
* @throws SOException
*/
public function encrypt($payload)
{
//Complete payload with timestamp and hash
date_default_timezone_set("UTC");
$payload['_timestamp'] = time();
$payload['_rnd'] = sha1($payload['_timestamp']);
//convert payload to JSON
$jsonPayload = json_encode($payload);
// Encrypt payload with AES CBC        
$ciphers = openssl_get_cipher_methods();
if (!in_array($this->_mode, $ciphers)) {
throw new SOException('No suitable cipher method available');
}
// Encrypt data with encryption key
$data = openssl_encrypt(
$jsonPayload,
$this->_mode,
$this->_encKey,
$this->_option,
$this->_iv
);
//Base64 encode iv . salt . data
$salt = openssl_random_pseudo_bytes(SOUtils::keylen() / 2);
$encData = base64_encode($this->_iv . $salt . $data);
// Sign with private signing  key
if (!openssl_sign(
$encData,
$signature,
$this->_signKey,
OPENSSL_ALGO_SHA1
)){
throw new SOException('Failed to sign data');
}
// Concat data with signature and base64 encode
$result = base64_encode($encData . '|' . $signature);
return $result;
Decryption
/**
*Constructor initialized with 3 keys
*@param string $encKey encryption key
*@param string $signKey signing key
*@param  string $pubKey public key
*@throws SOException
*/
public function__construct($encKey,$signKey,$pubKey)
{
if (!extension_loaded('openssl'))
{
throw newSOException('OpenSSLlib is not loaded');
}
if(SOUtils::strlen($encKey)!=SOUtils::keylen())
{
throw new SOException('Invalid encryption key length');
}
$this->_encKey = $encKey;
$this->_signKey = $signKey;
$this->_pubKey = $pubKey;
//Generate initialization vector
$this->_iv = openssl_random_pseudo_bytes(SOUtils::keylen()/2,$strong);
if(!$strong){
throw new SOException('OpenSSL version is out of date');
}
//keylen equals 32
$bitLength = 8 * SOUtils::keylen();
$this->_mode ='aes-'.$bitLength.'-cbc';
$this->_option =defined('OPENSSL_RAW_DATA')? OPENSSL_RAW_DATA:      
true;
}

SolidOpinion JavaScript API

For detailed information about
JavaScript API please follow this link.


Happy commenting!
SolidOpinion

Feedback and Knowledge Base