Swift
Swift
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 Swift Downloads
func chilkatTest() {
var success: Bool = false
// This example assumes the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
var integrationKey: String? = "DIMS3V5QDVG9J9ABRXC4"
var secretKey: String? = "HWVQ46nubLBxhnRlKddTltWIi3hL0fIQF2qTvLab"
let http = CkoHttp()!
http.accept = "application/json"
// Use your own hostname here:
var url: String? = "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.
http.login = integrationKey
http.password = secretKey
let req = CkoHttpRequest()!
req.addParam(name: "username", value: "matt")
req.addParam(name: "factor", value: "push")
// The device ID can be obtained from the preauth response. See Duo Preauth Example
req.addParam(name: "device", value: "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.
req.addParam(name: "async", value: "1")
req.httpVerb = "POST"
req.contentType = "application/x-www-form-urlencoded"
let resp = CkoHttpResponse()!
success = http.httpReq(url: url, request: req, response: resp)
if success == false {
print("\(http.lastErrorText!)")
return
}
print("status code = \(resp.statusCode.intValue)")
let json = CkoJsonObject()!
success = json.load(json: resp.bodyStr)
json.emitCompact = false
print("\(json.emit()!)")
if resp.statusCode.intValue != 200 {
return
}
// Sample successful output:
// status code = 200
// {
// "stat": "OK",
// "response": {
// "txid": "45f7c92b-f45f-4862-8545-e0f58e78075a"
// }
// }
var txid: String? = json.string(of: "response.txid")
// Use your own hostname here:
let sbUrl = CkoStringBuilder()!
sbUrl.append(value: "https://api-a03782e1.duosecurity.com/auth/v2/auth_status?txid=")
sbUrl.append(value: txid)
var url: String? = sbUrl.getAsString()
print("Auth status URL: \(url!)")
let sbResult = CkoStringBuilder()!
var responseStatus: String?
var responseStatus_msg: String?
// Wait for a response...
var i: Int = 0
var maxWaitIterations: Int = 100
while i < maxWaitIterations {
// Wait 3 seconds.
http.sleepMs(millisec: 3000)
print("Polling...")
success = http.httpNoBody(verb: "GET", url: url, response: resp)
if success == false {
print("\(http.lastErrorText!)")
return
}
if resp.statusCode.intValue != 200 {
print("error status code = \(resp.statusCode.intValue)")
print("\(resp.bodyStr!)")
print("Failed.")
return
}
// Sample response:
// {
// "stat": "OK",
// "response": {
// "result": "waiting",
// "status": "pushed",
// "status_msg": "Pushed a login request to your phone..."
// }
// }
json.load(json: resp.bodyStr)
// The responseResult can be "allow", "deny", or "waiting"
sbResult.clear()
json.string(ofSb: "response.result", sb: sbResult)
responseStatus = json.string(of: "response.status")
responseStatus_msg = json.string(of: "response.status_msg")
print("\(sbResult.getAsString()!)")
print("\(responseStatus!)")
print("\(responseStatus_msg!)")
print("")
if sbResult.contentsEqual(str: "waiting", caseSensitive: true) == true {
i = i + 1
}
else {
// Force loop exit..
i = maxWaitIterations
}
}
print("Finished.")
}