Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist
View authenticationService.cfc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
component persistent="false" accessors="true" output="false" {
 
property name="fw" type="any";
property name="apiUsersDAO" type="any";
 
public any function authenticateReuqest(required string verb,required string cfc,required struct requestArguments,required struct requestHeaders) {
if(!checkRequiredArguments(arguments.requestArguments)) {
return createAuthenticationRequiredMessage("Authentication Required: Missing Request Arguments.");
}
if(!havePrivateKey(arguments.requestArguments.publicKey)) {
return createAuthenticationRequiredMessage("Authentication Required: No API User By the Key given.");
}
//writeDump(createSignString(arguments.requestArguments));
//abort;
if(!timeInAcceptableBounds(arguments.requestArguments.timestamp)) {
return createAuthenticationRequiredMessage("Authentication Required: Request Time Out");
}
//writeDump(createSignString(arguments.requestArguments));
//writeDump(EncryptSignature(argValue=createSignString(arguments.requestArguments),publicKey=arguments.requestArguments.publicKey));
//abort;
// Since I already determined this timestamp was within acceptable bounds to be accepted,
// I still use it within my own hash calculation to make sure it was the same timestamp sent from the client originally in thier sign,
// and not a made-up timestamp from a man-in-the-middle attack.
if(!compareSignature(theirSign=arguments.requestArguments.signature,areSign=EncryptSignature(argValue=createSignString(arguments.requestArguments),publicKey=arguments.requestArguments.publicKey))) {
return createAuthenticationRequiredMessage("Signature does not match!");
}
return true;
}
public any function timeInAcceptableBounds(required any timestamp) hint="I check request was send within acceptable bounds." {
local.dif=DateDiff("n",arguments.timestamp,now());
if(local.dif gt 3) {
return false;
} else {
return true;
}
}
public any function compareSignature(required any theirSign,required any areSign) hint="I compare the two signatures." {
if(arguments.theirSign eq arguments.areSign) {
return true;
} else {
return false;
}
}
public any function EncryptSignature(required string argValue,required string publicKey) hint="I create my own signature that I will matching later." {
var jMsg=JavaCast("string",arguments.argValue).getBytes("iso-8859-1");
var jKey=JavaCast("string",getapiUsersDAO().getSecretKey(arguments.publicKey)).getBytes("iso-8859-1");
var key=createObject("java","javax.crypto.spec.SecretKeySpec");
var mac=createObject("java","javax.crypto.Mac");
key=key.init(jKey,"HmacSHA1");
mac=mac.getInstance(key.getAlgorithm());
mac.init(key);
mac.update(jMsg);
return lCase(binaryEncode(mac.doFinal(),'Hex'));
//return Encrypt(arguments.argValue,getapiUsersDAO().getSecretKey(arguments.publicKey),'HMAC-SHA1');
}
public string function createSignString(required struct requestArguments) hint="I create the string for my signature." {
StructDelete(arguments.requestArguments,"signature");
var myMap=createObject("java","java.util.TreeMap").init(arguments.requestArguments);
local.returnString="";
for(key in myMap) {
local.returnString=local.returnString & myMap[key];
}
return local.returnString;
}
public any function havePrivateKey(required string publicKey) hint="I check API User exisits and has a key." {
return getapiUsersDAO().hasPrivateKey(arguments.publicKey);
}
public any function checkRequiredArguments(required requestArguments) hint="I check we have the required arguments to authenticate this request." {
if(structkeyexists(arguments.requestArguments,"publicKey") AND structkeyexists(arguments.requestArguments,"signature") AND structkeyexists(arguments.requestArguments,"timestamp")) {
return true;
}
return false;
}
public any function createAuthenticationRequiredMessage(string message) {
local.bodyContent=structnew();
local.reponseObject=createObject("component","taffy.core.genericRepresentation");
bodycontent.msg=arguments.message;
return reponseObject.setData(local.bodyContent).withStatus(200);
}
/*public any function authenticateReuqest(required string verb,required string cfc,required struct requestArguments,required struct requestHeaders) {
// Check for Authorisation headers
if(not structkeyexists(arguments.requestHeaders,"Authorization")) {
return createAuthenticationRequiredMessage("Authentication Required");
}
// Check Authorization valid
local.apiAccess=retrieveApiUserFromAuthorizationHeader(arguments.requestHeaders["Authorization"]);
if(not len(local.apiAccess)) {
return createAuthenticationRequiredMessage("Invalid login credentials provided");
}
if(local.apiAccess eq true) {
return true;
}
return createAuthenticationRequiredMessage("Invalid login credentials provided");
}*/
public any function retrieveApiUserFromAuthorizationHeader(required string authorizationHeader) {
local.decodedAuthHeader=tostring(tobinary(listlast(arguments.authorizationHeader," ")));
local.username=ListFirst(local.decodedAuthHeader,":");
local.password=Listlast(local.decodedAuthHeader,":");
return validateLoginCredentials(local.username,local.password);
}
public any function validateLoginCredentials(required string login,required string password) {
local.result=getDAO().readByUserNameandPassword(arguments.login,arguments.password);
// If we have a match return true
if(!isNull(local.result)) {
return true;
}
// Default is always false.
return False;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.