Sample code for 30+ languages & platforms
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

C
#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);

    }