External Authentication with Third-Party Integration - Web Console

Table of Contents

Overview

Set up external authentication if you are connecting to the CommVault Web Console from an outside portal. When a user clicks through to the Web Console from an outside portal, the outside portal uses an HTTP request to send an encrypted JSON message to the Web Console. The Web Console decrypts the message and automatically logs in the user.

Obtaining an Application Key, Token, and Secret

The message sent to the Web Console must contain an encoded application key and an encrypted JSON message. The application token and application secret are used to encrypt the JSON message.

Prerequisite

Add the bEnableExternalApplicationSettings additional setting so External Application Settings is visible in the Others section of the control panel. For information on adding the additional setting, see Enabling External Application Settings.

Procedure

  1. From the CommCell Console ribbon, click the Home tab, and then click Control Panel.
  2. Under the Others section, click External Application Settings.
  3. In the External Application Settings dialog box, do one of the following:
    • Click Add to register a new application and to create an application key, application token, and application secret for the new application.
    • Select an existing application and click Renew to create a new application token and application secret for the existing application.
  4. In the External Application Settings dialog box, select the application and then click View to see the application key, token, and secret.

    For information on other commands available in the External Application Settings dialog box, see External Application Settings - Online Help.

Writing the Encryption Program

The JSON message sent to the Web Console must be encrypted, so an encryption program is needed. The encryption program must:

  • Use the application token and secret to encrypt the JSON message.

    For information on obtaining the application token and secret, see Obtaining an Application Key, Token, and Secret.

  • Use AES (Advanced Encryption Standard) with MD5 padding.

Sample

A sample encryption program written in Java is discussed below: SampleCryptoHelper.zip.

Libraries

The program uses the following libraries:

  • java.security.MessageDigest to provide the functionality of a message digest algorithm.
  • javax.crypto.Cipher to provide the functionality of a cipher for encryption and decryption.
  • javax.crypto.spec.SecretKeySpec to create a secret key.
  • org.apache.commons.codec.binary.Base64 to provide base64 encoding.

Parameters

This program takes the following parameters:

  • JSON message
  • application token
  • application secret

Program

The libraries are imported:

package client.thirdPartyLogin.handlers;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

The encryption program is defined as a public class so it can be called from the login handler program:

// Class name : CryptoHelper
// Purpose : Helper class for implementing encryption/decryption of payload for third party login at client side

public class CryptoHelper

The JSON message, application token, and application secret are passed in and the private class Cipher is called in ENCRYPT_MODE:

{
public String encrypt(String blobToEncrypt, String clientToken, String clientSecret) throws Exception {
return Base64.encodeBase64String(buildCypher(Cipher.ENCRYPT_MODE, clientToken, clientSecret).doFinal(
blobToEncrypt.getBytes()));
}

The JSON message, application token, and application secret are passed in and the private class Cipher is called in DECRYPT_MODE. Use the decryption mode to verify that the values are encrypted properly by decrypting the encrypted message and comparing it to the original value.

public String decrypt(String blobToDecrypt, String clientToken, String clientSecret) throws Exception {
return new String(buildCypher(Cipher.DECRYPT_MODE, clientToken, clientSecret).doFinal(
Base64.decodeBase64(blobToDecrypt)));
}

In the Cipher class, the application token and application secret are used as the key base for the AES encryption:

private Cipher buildCypher(int mode, String clientToken, String clientSecret) throws Exception {

String keyBase = clientSecret + clientToken;
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(keyBase.getBytes());
SecretKeySpec key = new SecretKeySpec(digest.digest(), 0, 16, "AES");
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(mode, key);
return aes;
}

}

Writing the Login Handler Program

A program is needed to form the encrypted JSON message and then to send the message to the Web Console. The output of the login handler program is an HTTP request with two parameters: the encoded application key and the encrypted JSON message. For example, http://client.mydomain.com/webconsole?key={value}&message={value}.

The following pieces of information are needed for this program:

  • Application token: used to encrypt the JSON object.
  • Application secret: used to encrypt the JSON object.
  • Validated user name: added to the JSON object as a key/value pair. This user name must exist in the CommCell Console.
  • Time stamp: added to the JSON object as a key/value pair. Use Coordinated Universal Time (UTC) in seconds.
  • Application key: encoded and sent in the HTTP request.
  • URL of the Web Console appended with /server/authCallback: sent in the HTTP request.

Sample

A sample login handler program written in Java is discussed below: SampleThirdPartyLoginHandler.zip.

Libraries

The program uses the following libraries:

  • java.io.IOException to handle I/O exceptions.
  • java.net.InetAddress to represent an IP address.
  • java.net.URL to represent a URL.
  • java.net.URLEncoder to handle HTML form encoding.
  • javax.servlet.http.HttpServletRequest to provide request information for HTTP servlets.
  • javax.servlet.http.HttpServletResponse to provide HTTP functionality when sending a response.
  • org.apache.commons.codec.binary.Base64 to provide base64 encoding.
  • org.apache.log4j.Logger to handle logging operations.
  • org.json.JSONObject to handle JSON objects.
  • commvault.web.util.UrlString to append the main URL with parameters. A sample of this type of library is available: URLString.zip.

Parameters

This program takes the following parameters:

  • application token
  • application secret
  • user name
  • time stamp
  • application key
  • encoded application key
  • length of the application key
  • URL of the Web Console
  • JSON message

Program

The libraries are imported:

package client.thirdPartyLogin.handlers;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.json.JSONObject;

import commvault.web.util.UrlString;

The login handler program is defined as a public class so it can be called from other programs:

public class ClientThirdPartyLogin

The variables are set:

{
private static final String THIRD_PARTY_PARAM_APPKEY = "key";
private static final String THIRD_PARTY_PARAM_MESSAGE = "message";
private static final String THIRD_PARTY_PARAM_USERNAME = "userName";
private static final String THIRD_PARTY_PARAM_TIMESTAMP = "timeStamp";
private static final Integer THIRD_PARTY_PARAM_APPKEY_SIZE = 15;
private static final String THIRD_PARTY_APP_KEY = "appKey";
private static final String THIRD_PARTY_APP_TOKEN = "appToken";
private static final String THIRD_PARTY_APP_SECRET = "appSecret";
private static final String THIRD_PARTY_URL = "targetWebConsoleURL";

 

//function Name : doThirdPartyLogin
//Purpose : To allow the client third party application to form the encrypted message and send it
//This function should be called only after client side authentication succeeds ie. "user name" passed to this function should be authentic

@RequestHandlerMethod(url = "thirdPartyLogin.do")
public void doThirdPartyLogin()

 

{
String targetURL = Util.getConfigProperty(THIRD_PARTY_URL);

The application key, application token, and application secret are retrieved from a storage location:

try {
//Fetch application Key , application Token & application secret from storage location(DB,file etc)
String inputAppKey = getProperty(THIRD_PARTY_APP_KEY);
String inputAppToken = getProperty(THIRD_PARTY_APP_TOKEN);
String inputAppSecret = getProperty(THIRD_PARTY_APP_SECRET);

 

//If the user name is not authenticated at client's end,authenticate it first and then assign it properly
String inputUserName = RequestContext.getRequest().getParameter("username");

The application key, application token, application secret, and user name are checked for null values and length. The length of the application key is checked against THIRD_PARTY_PARAM_APPKEY_SIZE, which is set to 15:

//Check for validity of application details fetched previously.
if (inputAppKey != null && inputAppKey.length() == THIRD_PARTY_PARAM_APPKEY_SIZE && inputAppToken != null
&& inputAppToken.length() > 0 && inputAppSecret != null && inputAppSecret.length() > 0
&& inputUserName != null && inputUserName.length() > 0) {

The application key is encoded in base64:

//Encode application key using standard Base64 encoding scheme.
String encodedAppKey = Base64.encodeBase64String(inputAppKey.getBytes());
if (encodedAppKey != null && encodedAppKey.length() > 0) {

The time stamp is UTC in seconds:

//Initialize request Time Stamp using UTC time in seconds
long requestTime = System.currentTimeMillis() / 1000L;

if (requestTime > 0) {

The JSON object is initialized using the user name and the time stamp:

//Initialize JSON object using UserName and Current UTC Time Stamp
JSONObject json = new JSONObject();
json.put(THIRD_PARTY_PARAM_USERNAME, inputUserName);
json.put(THIRD_PARTY_PARAM_TIMESTAMP, requestTime);

The JSON message is encrypted using the encryption program. The application token and application secret are used as the key base in the encryption program.

For more information on the encryption program, see Writing the Encryption Program.

//Encrypt the resultant JSON message using helper class [CryptoHelper]
CryptoHelper helper = new CryptoHelper();
String encryptedJSONString = helper.encrypt(json.toString(), inputAppToken, inputAppSecret);

The encoded application key and the encrypted JSON message are part of the HTTP request sent to the Web Console, for example: http://client.mydomain.com/webconsole/server/authCallback?key=sdfsdfsd&message=9087r24Q@#R@#@#:

//Now form the final HTTP request
UrlString requestString = new UrlString(targetURL.toString());
requestString.add(THIRD_PARTY_PARAM_APPKEY, encodedAppKey);
requestString.add(THIRD_PARTY_PARAM_MESSAGE, encryptedJSONString);

The HTTP request must be sent to the Web Console:

//Implement code here to send the final HTTP request to the Target Webconsole URL

If an error occurs, the error is sent to the log and the user is redirected to the outside portal using the redirectToClientPage function:

                return;
            } else {
              logger.warn("Failure in calculating Request TimeStamp");
              redirectToClientPage();
            }
        } else {
          logger.warn("Failure in creating Encoded AppKey");
          redirectToClientPage();
        }
      } else {
        logger.warn("Failure in getting some Input Parameters");
        redirectToClientPage();
      }
  } catch (Exception ex) {
    logger.warn("Third Party Client Side Failure. " + ex.getMessage());
    redirectToClientPage();
  }
}

The redirectToClientPage function redirects the user to the outside portal:

public void redirectToClientPage(){

//Implement code to redirect to the corresponding client page/URL to handle failure in forming/sending request for third party login.

    }
}