C
C
Duo Auth API - Async Auth
See more Duo Auth MFA Examples
If you enable async, then your application will be able to retrieve real-time status updates from the authentication process, rather than receiving no information until the process is complete.Chilkat C Downloads
#include <C_CkHttp.h>
#include <C_CkHttpRequest.h>
#include <C_CkHttpResponse.h>
#include <C_CkJsonObject.h>
#include <C_CkStringBuilder.h>
void ChilkatSample(void)
{
BOOL success;
const char *integrationKey;
const char *secretKey;
HCkHttp http;
const char *url;
HCkHttpRequest req;
HCkHttpResponse resp;
HCkJsonObject json;
const char *txid;
HCkStringBuilder sbUrl;
const char *url;
HCkStringBuilder sbResult;
const char *responseStatus;
const char *responseStatus_msg;
int i;
int maxWaitIterations;
success = FALSE;
// This example assumes the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
integrationKey = "DIMS3V5QDVG9J9ABRXC4";
secretKey = "HWVQ46nubLBxhnRlKddTltWIi3hL0fIQF2qTvLab";
http = CkHttp_Create();
CkHttp_putAccept(http,"application/json");
// Use your own hostname here:
url = "https://api-a03782e1.duosecurity.com/auth/v2/auth";
// This example requires Chilkat v9.5.0.89 or greater because Chilkat will automatically
// generate and send the HMAC signature for the requires based on the integration key and secret key.
CkHttp_putLogin(http,integrationKey);
CkHttp_putPassword(http,secretKey);
req = CkHttpRequest_Create();
CkHttpRequest_AddParam(req,"username","matt");
CkHttpRequest_AddParam(req,"factor","push");
// The device ID can be obtained from the preauth response. See Duo Preauth Example
CkHttpRequest_AddParam(req,"device","DP6GYVTQ5NK82BMR851F");
// Add the async param to get an immediate response, then periodically check for updates to find out when the MFA authentication completes for fails.
CkHttpRequest_AddParam(req,"async","1");
CkHttpRequest_putHttpVerb(req,"POST");
CkHttpRequest_putContentType(req,"application/x-www-form-urlencoded");
resp = CkHttpResponse_Create();
success = CkHttp_HttpReq(http,url,req,resp);
if (success == FALSE) {
printf("%s\n",CkHttp_lastErrorText(http));
CkHttp_Dispose(http);
CkHttpRequest_Dispose(req);
CkHttpResponse_Dispose(resp);
return;
}
printf("status code = %d\n",CkHttpResponse_getStatusCode(resp));
json = CkJsonObject_Create();
success = CkJsonObject_Load(json,CkHttpResponse_bodyStr(resp));
CkJsonObject_putEmitCompact(json,FALSE);
printf("%s\n",CkJsonObject_emit(json));
if (CkHttpResponse_getStatusCode(resp) != 200) {
CkHttp_Dispose(http);
CkHttpRequest_Dispose(req);
CkHttpResponse_Dispose(resp);
CkJsonObject_Dispose(json);
return;
}
// Sample successful output:
// status code = 200
// {
// "stat": "OK",
// "response": {
// "txid": "45f7c92b-f45f-4862-8545-e0f58e78075a"
// }
// }
txid = CkJsonObject_stringOf(json,"response.txid");
// Use your own hostname here:
sbUrl = CkStringBuilder_Create();
CkStringBuilder_Append(sbUrl,"https://api-a03782e1.duosecurity.com/auth/v2/auth_status?txid=");
CkStringBuilder_Append(sbUrl,txid);
url = CkStringBuilder_getAsString(sbUrl);
printf("Auth status URL: %s\n",url);
sbResult = CkStringBuilder_Create();
// Wait for a response...
i = 0;
maxWaitIterations = 100;
while (i < maxWaitIterations) {
// Wait 3 seconds.
CkHttp_SleepMs(http,3000);
printf("Polling...\n");
success = CkHttp_HttpNoBody(http,"GET",url,resp);
if (success == FALSE) {
printf("%s\n",CkHttp_lastErrorText(http));
CkHttp_Dispose(http);
CkHttpRequest_Dispose(req);
CkHttpResponse_Dispose(resp);
CkJsonObject_Dispose(json);
CkStringBuilder_Dispose(sbUrl);
CkStringBuilder_Dispose(sbResult);
return;
}
if (CkHttpResponse_getStatusCode(resp) != 200) {
printf("error status code = %d\n",CkHttpResponse_getStatusCode(resp));
printf("%s\n",CkHttpResponse_bodyStr(resp));
printf("Failed.\n");
CkHttp_Dispose(http);
CkHttpRequest_Dispose(req);
CkHttpResponse_Dispose(resp);
CkJsonObject_Dispose(json);
CkStringBuilder_Dispose(sbUrl);
CkStringBuilder_Dispose(sbResult);
return;
}
// Sample response:
// {
// "stat": "OK",
// "response": {
// "result": "waiting",
// "status": "pushed",
// "status_msg": "Pushed a login request to your phone..."
// }
// }
CkJsonObject_Load(json,CkHttpResponse_bodyStr(resp));
// The responseResult can be "allow", "deny", or "waiting"
CkStringBuilder_Clear(sbResult);
CkJsonObject_StringOfSb(json,"response.result",sbResult);
responseStatus = CkJsonObject_stringOf(json,"response.status");
responseStatus_msg = CkJsonObject_stringOf(json,"response.status_msg");
printf("%s\n",CkStringBuilder_getAsString(sbResult));
printf("%s\n",responseStatus);
printf("%s\n",responseStatus_msg);
printf("\n");
if (CkStringBuilder_ContentsEqual(sbResult,"waiting",TRUE) == TRUE) {
i = i + 1;
}
else {
// Force loop exit..
i = maxWaitIterations;
}
}
printf("Finished.\n");
CkHttp_Dispose(http);
CkHttpRequest_Dispose(req);
CkHttpResponse_Dispose(resp);
CkJsonObject_Dispose(json);
CkStringBuilder_Dispose(sbUrl);
CkStringBuilder_Dispose(sbResult);
}