Single Sign-on (Multipass / Token-Based / Cookie-Based)

About Single Sign-On

What is Single Sign-On and why should I use it?

Single Sign-On is an increasingly popular method of integrating your site's user details with IdeaScale's authentication system. The benefit to configuring an SSO integration is that it alleviates the user's need to log in to IdeaScale with yet another set of credentials. With SSO employed, access to the IdeaScale community is pre-determined by the user's access to your intranet. SSO removes the login process--which many community admins feel is a significant barrier to participation.

What kinds of Single Sign-On does IdeaScale support?

IdeaScale supports Cookie-Based (HMAC), Token-Based/Multipass, and SAML 2.0/Shibboleth.

Multipass SSO

A Multipass is simply a hash of keys and values, provided as an AES encrypted JSON hash. The keys are:

Name Value
name The name of the user
ssoId The user's login id (username or email)
email The user's email address, e.g. user@gmail.com
expires Token expiry date. Example ISO-8601 format: "yyyy-MM-dd'T'HH:mm:ss.SSSZ". Note:

Once your JSON hash is constructed, you'll want to encrypt it with an AES key using your site key as a password, and your api key as a salt. The IV used should be 16 bytes of zeros.

Building the Multipass

1) Pick an expiration date for the hash, like 5 minutes from now: 2011-05-04T12:34:56.789-0700
2) Start with a JSON hash of data: {"ssoId":"john.ideascale.com",email":"john@ideascale.com","name":"John Doe","expires":"2011-05-04T12:34:56.789-0700"}
3) Encrypt with AES and Base64 the resulting data:
4) Since these Base64 strings are being passed around the web, IdeaScale prefers a URL-safe variant. However, if your Base64 string is properly escaped for URLs, it'll still work. Here's how the Base64 can be converted to the URL-safe variant:

1) Remove any newlines. Matching Regex: (\n+)
2) Remove trailing = characters. Matching Regex: (=+)$
3) Convert any + characters to -. Matching Regex: (+)
4) Convert any / characters to _. Matching Regex: (\)

Multi-Pass Code Samples

Click here to visit our repository of IdeaScale-compatible Multipass/SSO implementations on GitHub. The repository provides examples in several popular languages.

Cookie-Based SSO

How does Cookie based SSO option work?

The cookie-based SSO option is for sites that already have an authentication model in place using a browser/login session. In such cases, the system can use a shared cookie model to determine if a user is authenticated or not. Here is a general overview of the IdeaScale SSO process:

  1. IdeaScale user visits your community
  2. IdeaScale checks for a specific cookie
  3. If cookie isn't present, IdeaScale redirects to your authentication page
  4. The user completes your authentication steps
  5. Your authentication page writes a cookie to users browser (cookie includes payload such as email address, first name, last name, etc)
  6. The authentication page re-directs back to your IdeaScale community.
  7. IdeaScale again checks for the cookie, using the data in the payload to provision the user (if user has not been provisioned already).

What are the steps in implementing a Cookie based SSO?

  1. Your authentication system (after user logs in) must set a SESSION LEVEL (Expires when browser is closed) and a DOMAIN LEVEL cookie. You can name the Cookie anything you want. The value of the cookie should be a DES Encrypted and Base64 Encoded String of the user's email address.
  2. Domain Level Cookie (Domain=.mycompany.com)
  3. Session Level Cookie (Timeout = When Browser Closes)
  4. Cookie Name (Anything You want, must match 'Site Name (Identity Provider)' in SSO Settings)
  5. Cookie Value (DES Encrypted + Base64 Encoded String of the user's email address)
  6. Setup your IdeaScale community with a Custom Domain URL (ideas.mycompany.com).
  7. Click on the settings tab, and then "Single Sign On" in the left hand corner:
    1. Change the "Single Sign-On Type" to "Domain Cookie Based Cookie Based Single-Signon"
    2. Authentication URL: is the URL that the system will redirect to if a users comes to your site without a cookie. This is usually your login screen on your intranet/site.
    3. DES key: 8 character string
    4. Site Name: The Name of the Cookie you used in Step 1 and Step 4 above. This has to match the same name.

ideascale-sso-settings.png

Can I pass in other variables (firstname, lastname etc.)?

By default the value of the cookie is the SSO ID (username or email) in this format:

jon@mycompany.com

In cases where multiple values (like first name and last name) need to be passed, change the value of the cookie to be of this format:

ssoId=jon@mycompany.com&email=jon@mycompany.com&firstname=Jon&lastname=Doe&custom1=Seattle&custom2=US&custom3=Employee

Note:

  • You can have UPTO 5 CUSTOM VARIABLES attached to a user.
  • Each Custom Variable can hold maximum 128 characters.

For example: *

String cookieValue = desEncript("ssoId=jon@mycompany.com&email=jon@mycompany.com&firstname=Jon&lastname=Doe&custom1=Seattle&custom2=US&custom3=Employee");
response.setCookie("viraj_sso_cookie", cookieValue);

Do I need to setup a DOMAIN Level Cookie?

Yes - The cookie has to be at the DOMAIN Level (.mycompany.com) and NOT at the host level.

What DES encryption mode should I use?

Please use the ECB mode.

The API I use requires me to set the padding mode. Which padding mode should I use?

Please use the PAD_PKCS5 mode.

Is there a way I can test my configuration?

Yes. The following URL can be used to test your setup.

http://[yourcommunity_url]/a/jsp/useradmin/cookie-test.jsp

I would like to customize the Login/Signup instructions

If Single Sign-On is enabled on your portal, you will see an additional option to customize the text of the SSO.

ideascale-sso-instructions.png

Sample DES Encryption Code


Java

public static String encriptDES(String passPhrase, String value) throws Exception {
    SecretKey key = new SecretKeySpec(passPhrase.getBytes(), "DES");
    // Create the ciphers
    Cipher ecipher = Cipher.getInstance(key.getAlgorithm());
    // Encode the string into bytes using utf-8
    ecipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] utf8 = value.getBytes("UTF8");    
    // Encrypt
    byte[] enc = ecipher.doFinal(utf8);   
    // Encode bytes to base64 to get a string
    return new sun.misc.BASE64Encoder().encode(enc);
} 
public static String decriptDES(String passPhrase, String value)
    throws Exception, IllegalBlockSizeException {
    SecretKey key = new SecretKeySpec(passPhrase.getBytes(), "DES");
    Cipher dcipher = Cipher.getInstance(key.getAlgorithm());   
    // Create the ciphers
    dcipher.init(Cipher.DECRYPT_MODE, key);
    byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(value);    
    // Decrypt
    byte[] utf8 = dcipher.doFinal(dec);    
    // Decode using utf-8
    return new String(utf8, "UTF8");
}