Background
KPOINT supports OAuth and SAML as standard authentication and authorization mechanisms when integrating with third-party applications. These mechanisms work in cases where KPOINT sits as a peer enterprise web application integrating with other applications in the enterprise space.
When KPOINT integrates with applications in slave mode (sits behind another enterprise application), it expects other applications to implement OAuth (as provider) or SAML (as authority). When this is not possible, token based authentication mechanism can be used. Token based approach provides a mechanism which would allow the "master" application to pass down a token, constructed using a standard mechanism, which will allow KPOINT to validate that the user has been authenticated by the trusted master applicaition. Once KPOINT is able to ascertain the identity of the user, it will be able to provide appropriate services to the user based on her authorization.
Using the token based authenticaton mechanism
This authentication mechanism applies to all service access points in this document.
To do this, the integrating application adds the parameter called “xt”
(Base64 urlsafe encoded HMAC or DSA token) to the request.
Prerequisites for token generation
Token Generation
Token Generation Code Snippet for PHP
<?php
$kpointDomain="http://acme.kpoint.com";
$CLIENT_ID = "ci9XXXXXXXXXXXXXXXXXXXXXXXXXXXXX0";
$SECRET_KEY = "sk4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6";
$displayname= "John Doe";
$email = "john.doe@fakeorg.com";
$challenge = time();
$account_number = "EMPID1000"; // optional
/*
* xauth_token generation part
*/
//
// step 1
// if user is to be authenticated with email-id, then
$data = "$CLIENT_ID:$email:$displayname:$challenge";
// if you want to authenticate user with only account number, or email is not available, then
$email = "";
$data = "$CLIENT_ID:$email:$displayname:$challenge:$account_number";
// if you want to authenticate user with both email and account number, then
$data = "$CLIENT_ID:$email:$displayname:$challenge:$account_number";
//step 2
$xauth_token = hash_hmac("md5", $data, $SECRET_KEY, true);
//step 3
$b64token = base64_encode($xauth_token);
$b64token = str_replace("=","", $b64token);
$b64token = str_replace("+","-", $b64token);
$b64token = str_replace("/","_", $b64token);
//step 4
// if user is to be authenticated with email-id, then
$xtencode= "client_id=$CLIENT_ID&user_email=$email&user_name=$displayname&challenge=$challenge&xauth_token=$b64token";
// if you want to authenticate user with only account number, or email is not available, then
$xtencode= "client_id=$CLIENT_ID&user_name=$displayname&challenge=$challenge&user_account_number=$account_number&xauth_token=$b64token";
// if you want to authenticate user with both email and account number, then
$xtencode= "client_id=$CLIENT_ID&user_email=$email&user_name=$displayname&challenge=$challenge&user_account_number=$account_number&xauth_token=$b64token";
/*
* xt token generation part
*/
//step 5
$xt= base64_encode($xtencode);
$xt = str_replace("=","", $xt);
$xt = str_replace("+","-", $xt);
$xt = str_replace("/","_", $xt);
//step 6
echo "<iframe width='100%' height='100%' src='http://acme.kpoint.com/web/videos/gcc-3ec87a06-aabc-4a81-848d-2ab4089839d4/nv4/embedded?xt=$xt'></iframe>";
?>
Token Generation Code Snippet for Python
import time, hmac, base64, hashlib
CLIENT_ID=<client_id>
SECRET_KEY=<secret_key>
def _generate_xauth_token(email, displayname):
challenge = str(int(time.time()))
xauth_message = CLIENT_ID + ":" + email + ":" + displayname+ ":" + challenge
hmacToken = hmac.new(str(SECRET_KEY), str(xauth_message), hashlib.md5)
xauth_token=base64.urlsafe_b64encode(hmacToken.digest()).replace("=","")
xtencode= "client_id="+ CLIENT_ID +"&user_email="+ email +"&user_name="+ displayname +"&challenge="+challenge+"&xauth_token="+xauth_token;
xt=base64.urlsafe_b64encode(xtencode).replace("=","")
return xt
xttoken = _generate_xauth_token(<user_email>, <user_displayname>)
return xttoken
Token Generation Code Snippet for Java
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
private static final String CLIENT_ID = <client_id>;
private static final String CLIENT_SECRET = <client_secret>;
private String generateAccessToken(String email, String displayName) throws InvalidKeyException,
NoSuchAlgorithmException {
long challange = System.currentTimeMillis() / 1000;
String data = CLIENT_ID + ":" + email + ":" + displayName + ":"
+ challange;
String xauthToken = this.stringToBase64HMACMD5(data);
String xtEncode = "client_id=" + CLIENT_ID + "&user_email=" + email
+ "&user_name=" + displayName + "&challenge=" + challange
+ "&xauth_token=" + xauthToken;
String xt = Base64.encodeBase64URLSafeString(xtEncode.getBytes());
return xt;
}
private String stringToBase64HMACMD5(String message)
throws NoSuchAlgorithmException, InvalidKeyException {
SecretKeySpec keySpec = new SecretKeySpec(CLIENT_SECRET.getBytes(),
"HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(keySpec);
byte[] rawHmac = mac.doFinal(message.getBytes());
String xt = Base64.encodeBase64URLSafeString(rawHmac);
return xt;
}
Token Generation Code Snippet for DotNet
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Text;
using System.Security.Cryptography;
namespace TokenGenerationProj
{
class Program
{
public string KPointToken()
{
const string SECRET_KEY = "sk4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6";
const string displayname = "John Doe";
const string email = "john.doe@fakeorg.com";
const string CLIENT_ID = "ci9XXXXXXXXXXXXXXXXXXXXXXXXXXXXX0";
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
string Dttime = Convert.ToInt64((DateTime.UtcNow.ToUniversalTime() - epoch).TotalSeconds).ToString();
string xt = "";
Encoding encoding = Encoding.UTF8;
string message = CLIENT_ID + ":" + email + ":" + displayname + ":" + Dttime;
var keyByte = encoding.GetBytes(SECRET_KEY);
using (var hmacmd5 = new HMACMD5(keyByte))
{
byte[] hash = hmacmd5.ComputeHash(encoding.GetBytes(message));
string xauthToken = Base64Encode(hash);
xauthToken= xauthToken.Replace("=", "");
xauthToken = xauthToken.Replace("+", "-");
xauthToken = xauthToken.Replace("/", "_");
string xtEncode = "client_id=" + CLIENT_ID + "&user_email=" + email
+ "&user_name=" + displayname + "&challenge=" + Dttime
+ "&xauth_token=" + xauthToken;
xt = Base64Encode(System.Text.Encoding.UTF8.GetBytes(xtEncode));
xt = xt.Replace("=", "");
xt = xt.Replace("+", "-");
xt = xt.Replace("/", "_");
}
return xt;
}
private string Base64Encode(byte[] plainText)
{
return System.Convert.ToBase64String(plainText);
}
}
}
Token Generation Code Snippet for NodeJs(Server side)
function createAuthToken() {
var CLIENT_ID = "ci9XXXXXXXXXXXXXXXXXXXXXXXXXXXXX0";
var SECRET_KEY = "sk4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6";
var email = "john.doe@fakeorg.com";
var displayname = "John Doe";
var challenge = Math.round(new Date().getTime() / 1000);
var account_number = "EMPID1000";
var data = CLIENT_ID + ":" + email + ":" + displayname + ":" + challenge;
var hmac = crypto.createHmac('MD5', SECRET_KEY);
hmac.update(data);
var hash = hmac.digest('base64');
hash = hash.replace(/=/g, "");
hash = hash.replace(/\+/g, "-");
hash = hash.replace(/\//g, "_");
$xt_token_code = "client_id=" + CLIENT_ID + "&user_email=" + email + "&user_name=" + displayname + "&challenge=" + challenge + "&xauth_token=" + hash;
var xt = Buffer.from($xt_token_code)
.toString('base64');
xt = xt.replace(/=/g, "");
xt = xt.replace(/\+/g, "-");
xt = xt.replace(/\//g, "_");
return xt;
}
Token Generation Code Snippet for Salesforce - Java
String CLIENT_ID = 'cixxxxxxxxxxxxxxxxxxxxxxxxxxxxf3';
String CLIENT_SECRET = 'skxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxc2';
public String getKPointToken(String email, String displayname) {
long challange = System.currentTimeMillis() / 1000;
String data = CLIENT_ID + ':' + email + ':' + displayName + ':'+ challange;
//system.debug('### data: ' + data);
Blob xauthTokenTemp = crypto.generateMac('hmacMD5', Blob.valueOf(data), Blob.valueOf(CLIENT_SECRET));
String xauthToken = EncodingUtil.base64Encode(xauthTokenTemp);
//system.debug('### xauthToken: ' + xauthToken);
/// Replace the chars
xauthToken = xauthToken.replaceAll('=','');
xauthToken = xauthToken.replaceAll('\\+','-');
xauthToken = xauthToken.replaceAll('/','_');
string xtEncode = 'client_id=' + CLIENT_ID + '&user_email=' + email + '&user_name=' + displayName + '&challenge=' + challange + '&xauth_token=' + xauthToken;
//system.debug('### xtEncode: ' + xtEncode);
String xt = EncodingUtil.base64Encode(Blob.valueOf(xtEncode));
//system.debug('### xt: ' + xt);
/// Replace the chars
xt = xt.replaceAll('=','');
xt = xt.replaceAll('\\+','-');
xt = xt.replaceAll('/','_');
return xt;
}
Request URL
http://acme.kpoint.com/app/api/v2/auth/logout
Method
GET
Response
200 OK {
"result":true
}
Developer Notes
Clients make authenticated token requests using the "Authorization" request header field. Alternatively, clients MAY attempt to include the access token using the HTTP request URI in the query component or in the HTTP body when using application/x-www-form-urlencoded. Clients SHOULD only use the request URI or body when the "Authorization" request header field is not available, and MUST NOT use more than one method in each request.
The Authorization Request Header Field: The "Authorization" request header field is used by clients to make authenticated token requests. The client uses the "OAuth" authentication scheme to include the access token in the request.
GET /resource HTTP/1.1
Host: server.example.com
Authorization: OAuth vF9dft4qmT
URI Query Paramter: When including the access token in the HTTP request URI, the client adds the access token to the request URI query component.
GET /resource?oauth_token=vF9dft4qmT HTTP/1.1
Host: server.example.com
Form-Encoded Body Parameter: When including the access token in the HTTP request entity-body, the client adds the access token to the request body using the "oauth token" parameter.
POST /resource HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
oauth_token=vF9dft4qmT