실시간 웹훅 구성

이 페이지에서는 DUO와의 연동을 지원하는 실시간 웹훅을 구성하는 방법을 설명합니다.

시작하기 전에

API 클라이언트에서 액세스 토큰을 얻었는지 확인합니다.

프로시저

다음 CURL 예제를 사용하여 실시간 웹훅을 생성하세요.

이 예제에서는 다음 값을 대체합니다.
{{DUO API Hostname}}
DUO 테넌트 인증 API 애플리케이션 구성의 API hostname .
{{DUO Integration key}}
DUO 테넌트 인증 API 애플리케이션 구성의 Integration key .
{{tenant}}
Verify 테넌트 이름입니다.
{{access token}}
클라이언트 신임 정보에서 얻은 액세스 토큰입니다.

Web후크 예제 CURL

curl --location --request POST 'https://{{tenant}}/v1.0/webhooks-mgmt/' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {{access token}}}}' \
--data-raw '{
    "name": "DUO MFA Provider",
    "type": "realtime",
    "urls": ["{{DUO API Hostname}}"],
    "authentication": {
        "type": "header",
        "header": {
            "values":[
                {
                    "key": "hdr_integration_key",
                    "value": "{{DUO Integration key}}"
                },
                {
                    "key": "hdr_signing_key",
                    "value": "{{DUO Secret key}}"
                }
            ]
        }
    },
    "resources": {
        "enrollments": {
            "suffix": "/auth/v2/preauth",
            "method": "POST",
            "transform": {
                "outgoing": "{\"body\":jsonToFormURLEncoded({\"username\":body.username}, true), \"skip_authentication\": true, \"header\": header.put(\"date\", formatTime(now, '\''02 Jan 06 15:04 -0700'\'')).put(\"content-type\", \"application/x-www-form-urlencoded\").put(\"accept\", \"application/json\").put(\"authorization\", \"Basic \" + joinStrings([authentication_header.hdr_integration_key, hmacSha1(joinStrings([formatTime(now, '\''02 Jan 06 15:04 -0700'\''),method.toUpper(), host, path.toLower(), jsonToFormURLEncoded({\"username\":body.username}, true)], \"\\n\"), authentication_header.hdr_signing_key)], \":\").base64Encode())}",
                "incoming": "{\"body\": has(body.response) && has(body.response.devices) ? body.response.devices.map(d, d.capabilities.filter(c, c != \"auto\").map(c, {\"id\": d.device, \"capability\": c == \"mobile_otp\" ? \"hotp\" : c == \"sms\" ? \"smsotp\" : c, \"attributes\": {\"deviceName\": has(d.name) ? d.name : \"\", \"deliveryAddress\": has(d.number) ? d.number : \"\", \"authExecutionFlow\": c == \"mobile_otp\" ? \"validate\" : c == \"push\" ? \"init_then_poll\" : \"init_then_validate\"}})).flatten() : []}"
            }
        },
        "initiate": {
            "suffix": "/auth/v2/auth",
            "method": "POST",
            "transform": {
                "outgoing": "{\"body\":jsonToFormURLEncoded({\"async\":\"1\", \"device\":body.id, \"factor\": body.capability == \"smsotp\" ? \"sms\" : body.capability, \"username\":body.attributes.username}, true), \"skip_authentication\": true, \"header\": header.put(\"date\", formatTime(now, '\''02 Jan 06 15:04 -0700'\'')).put(\"content-type\", \"application/x-www-form-urlencoded\").put(\"accept\", \"application/json\").put(\"authorization\", \"Basic \" + joinStrings([authentication_header.hdr_integration_key, hmacSha1(joinStrings([formatTime(now, '\''02 Jan 06 15:04 -0700'\''),method.toUpper(), host, path.toLower(), jsonToFormURLEncoded({\"async\":\"1\", \"device\":body.id, \"factor\": body.capability == \"smsotp\" ? \"sms\" : body.capability, \"username\":body.attributes.username}, true)], \"\\n\"), authentication_header.hdr_signing_key)], \":\").base64Encode())}",
                "incoming": "{\"body\": has(body.response) && has(body.response.txid) ? {\"transactionId\": body.response.txid, \"status\": \"PENDING\"} : {\"status\": \"FAILED\"}}"
            }
        },
        "validate": {
            "suffix": "/auth/v2/auth",
            "method": "POST",
            "transform": {
                "outgoing": "{\"body\":jsonToFormURLEncoded({\"factor\": \"passcode\", \"passcode\": body.attributes.passvalue, \"username\":body.attributes.username}, true), \"skip_authentication\": true, \"header\": header.put(\"date\", formatTime(now, '\''02 Jan 06 15:04 -0700'\'')).put(\"content-type\", \"application/x-www-form-urlencoded\").put(\"accept\", \"application/json\").put(\"authorization\", \"Basic \" + joinStrings([authentication_header.hdr_integration_key, hmacSha1(joinStrings([formatTime(now, '\''02 Jan 06 15:04 -0700'\''),method.toUpper(), host, path.toLower(), jsonToFormURLEncoded({\"factor\": \"passcode\", \"passcode\": body.attributes.passvalue, \"username\":body.attributes.username}, true)], \"\\n\"), authentication_header.hdr_signing_key)], \":\").base64Encode())}",
                "incoming": "{\"body\": has(body.response) && has(body.response.result) ? {\"status\": body.response.result == \"allow\" ? \"SUCCESS\" : \"FAILED\", \"attributes\": body.response} : {\"status\": \"FAILED\"}}"
            }
        },
        "hotp_1": {
            "suffix": "/auth/v2/auth",
            "method": "POST",
            "transform": {
                "outgoing": "{\"body\":jsonToFormURLEncoded({\"factor\": \"passcode\", \"passcode\": body.attributes.passvalue, \"username\":body.attributes.username}, true), \"skip_authentication\": true, \"header\": header.put(\"date\", formatTime(now, '\''02 Jan 06 15:04 -0700'\'')).put(\"content-type\", \"application/x-www-form-urlencoded\").put(\"accept\", \"application/json\").put(\"authorization\", \"Basic \" + joinStrings([authentication_header.hdr_integration_key, hmacSha1(joinStrings([formatTime(now, '\''02 Jan 06 15:04 -0700'\''),method.toUpper(), host, path.toLower(), jsonToFormURLEncoded({\"factor\": \"passcode\", \"passcode\": body.attributes.passvalue, \"username\":body.attributes.username}, true)], \"\\n\"), authentication_header.hdr_signing_key)], \":\").base64Encode())}",
                "incoming": "{\"body\": has(body.response) && has(body.response.result) ? {\"status\": body.response.result == \"allow\" ? \"SUCCESS\" : \"FAILED\", \"attributes\": body.response} : {\"status\": \"FAILED\"}}"
            }
        },
        "result": {
            "suffix": "/auth/v2/auth_status",
            "method": "GET",
            "transform": {
                "outgoing": "{\"query\": {\"txid\": body.transactionId}, \"skip_authentication\": true, \"header\": header.put(\"date\", formatTime(now, '\''02 Jan 06 15:04 -0700'\'')).put(\"content-type\", \"application/x-www-form-urlencoded\").put(\"accept\", \"application/json\").put(\"authorization\", \"Basic \" + joinStrings([authentication_header.hdr_integration_key, hmacSha1(joinStrings([formatTime(now, '\''02 Jan 06 15:04 -0700'\''),method.toUpper(), host, path.toLower(), jsonToFormURLEncoded({\"txid\": body.transactionId}, true)], \"\\n\"), authentication_header.hdr_signing_key)], \":\").base64Encode())}",
                "incoming": "{\"body\": has(body.response) && has(body.response.result) ? {\"status\": body.response.result == \"allow\" ? \"SUCCESS\" : body.response.result == \"waiting\" || (body.response.result == \"deny\" && body.response.status == \"sent\") ?\"PENDING\" : body.response.status == \"timeout\" ? \"TIMEOUT\" : \"FAILED\", \"attributes\": body.response} : {\"status\": \"FAILED\"}}"
            }
        }
    },
    "purpose": ["external_mfa"]
}'
작성된 Web후크의 응답 본문에서 id을(를) 기록해 두십시오. DUO 외부 MFA 제공자를 구성해야 합니다.