API Gateway berbasis cloud mendukung autentikasi global, autentikasi tingkat entri rute, dan otorisasi konsumen untuk memastikan hanya permintaan yang sah yang dapat mengakses layanan. Topik ini menjelaskan cara menggunakan autentikasi dan otorisasi di API Gateway berbasis cloud agar konsumen dapat mengakses sumber daya secara aman.
Informasi latar belakang
Autentikasi dan otorisasi global ideal untuk skenario business-to-consumer (B2C), seperti logon terpadu. Sebaliknya, autentikasi konsumen tingkat entri rute dan tingkat API dirancang untuk skenario business-to-business (B2B), seperti memberikan akses API kepada mitra.
Perbandingan | Otentikasi dan Otorisasi Global | Autentikasi entri rute + Otorisasi konsumen |
Skenario | Skema berorientasi pelanggan (ToC), seperti logon dan autentikasi terpadu. | Skema B2B, seperti memberikan akses API kepada mitra. |
Perbedaan Inti | Saat Anda mengaktifkan autentikasi, otorisasi juga diaktifkan. | Setelah Anda mengaktifkan autentikasi, Anda harus mengonfigurasi otorisasi secara terpisah. |
Titik masuk konfigurasi | . |
|
Konfigurasi metode autentikasi (menggunakan autentikasi JWT sebagai contoh) |
|
|
Konfigurasi metode otorisasi | Saat membuat konfigurasi, masukkan daftar Domain Names dan Paths untuk daftar hitam atau daftar putih.
|
|
Catatan
Setelah Anda mengaktifkan autentikasi konsumen, kebijakan langsung berlaku. Jika entri rute atau API sudah dipublikasikan tetapi belum memiliki konsumen atau aturan otorisasi yang dikonfigurasi, semua permintaan akses akan ditolak secara default.
Menggunakan autentikasi dan otorisasi konsumen
Otentikasi JWT
Tinjauan alur autentikasi JWT
Klien mengirim permintaan autentikasi ke API Gateway. Permintaan biasanya berisi nama pengguna dan kata sandi pengguna akhir.
Gerbang meneruskan permintaan langsung ke layanan backend.
Layanan backend membaca dan memvalidasi informasi verifikasi, seperti nama pengguna dan kata sandi, dari permintaan tersebut. Setelah informasi divalidasi, layanan menggunakan kunci privat untuk menghasilkan token standar dan mengembalikannya ke gerbang.
Gerbang mengembalikan respons yang berisi token ke klien. Klien harus menyimpan cache token ini secara lokal.
Klien mengirim permintaan bisnis ke API Gateway dengan token tersebut.
Gerbang menggunakan kunci publik yang dikonfigurasi pengguna untuk memverifikasi token dalam permintaan. Setelah verifikasi berhasil, permintaan diteruskan ke layanan backend.
Layanan backend memproses logika bisnis dan mengirim respons.
Gerbang mengembalikan respons bisnis ke klien.
Bagian berikut menjelaskan cara menghasilkan token, cara klien mengirim permintaan ke gerbang, dan cara gerbang menggunakan kunci publik yang dikonfigurasi untuk memverifikasi token.
Menghasilkan token dengan layanan autentikasi
Contoh Java berikut menunjukkan cara menghasilkan token. Untuk bahasa lain, gunakan alat yang sesuai untuk menghasilkan pasangan kunci.
Buat proyek Maven dan tambahkan dependensi berikut:
Pertama, buat proyek Maven dan tambahkan dependensi berikut:
<dependency> <groupId>org.bitbucket.b_c</groupId> <artifactId>jose4j</artifactId> <version>0.7.0</version> </dependency>Pilih metode untuk menghasilkan token.
Anda dapat menghasilkan token menggunakan kunci simetris atau kunci asimetris. Pilih metode yang sesuai dengan kebutuhan Anda.
Menghasilkan token menggunakan kunci simetris
Contoh kode:
package org.example; import java.io.UnsupportedEncodingException; import java.security.PrivateKey; import org.jose4j.base64url.Base64; import org.jose4j.json.JsonUtil; import org.jose4j.jwk.OctJwkGenerator; import org.jose4j.jwk.OctetSequenceJsonWebKey; import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jws.JsonWebSignature; import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.NumericDate; import org.jose4j.keys.HmacKey; import org.jose4j.lang.JoseException; import sun.lwawt.macosx.CSystemTray; public class Main { public static void main(String[] args) throws JoseException, UnsupportedEncodingException { // Gunakan contoh dari topik ini String privateKeyJson = "{\n" + " \"k\": \"VoBG-oyqVoyCr9G56ozmq8n_rlDDyYMQOd_DO4GOkEY\",\n" + " \"kty\": \"oct\",\n" + " \"alg\": \"HS256\",\n" + "}"; JwtClaims claims = new JwtClaims(); claims.setGeneratedJwtId(); claims.setIssuedAtToNow(); // Atur waktu kedaluwarsa kurang dari 7 hari NumericDate date = NumericDate.now(); date.addSeconds(120*60); claims.setExpirationTime(date); claims.setNotBeforeMinutesInThePast(1); // Tambahkan parameter kustom. Semua nilai harus bertipe String. // Atur ID konsumen claims.setClaim("uid", "11215ac069234abcb8944232b79ae711"); JsonWebSignature jws = new JsonWebSignature(); // Atur algoritma enkripsi jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256); jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString()))); jws.setPayload(claims.toJson()); String jwtResult = jws.getCompactSerialization(); System.out.println("Hasil Token Web JSON yang dihasilkan adalah: \n" + jwtResult); } }Pengaturan kode:
privateKeyJson: Ini adalah JSON Web Key Set (JWKS) yang digunakan saat Anda membuat konsumen. Anda dapat mencatat JWKS saat membuat konsumen atau mengambilnya nanti dari halaman konfigurasi dasar konsumen.Atur ID konsumen. Misalnya,
claims.setClaim("uid", "11215ac069234abcb8944232b79ae711"). Konsol menghasilkan ID konsumen default saat Anda membuat konsumen. Anda dapat mengubah ID ini sesuai kebutuhan. Anda juga dapat mengambil ID konsumen dari halaman konfigurasi dasar konsumen.Atur algoritma enkripsi. Misalnya,
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256). Algoritma ini harus sesuai dengan yang ada di JWKS.CatatanAlgoritma enkripsi yang didukung adalah ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512, HS256, HS384, HS512, dan EdDSA.
Saat menggunakan enkripsi simetris, dekode nilai "k".
jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString())));
Atur waktu kedaluwarsa. Waktu kedaluwarsa harus kurang dari 7 hari. Setelah token kedaluwarsa, Anda harus menghasilkannya kembali untuk memastikan keamanan.
... NumericDate date = NumericDate.now(); date.addSeconds(120*60); claims.setExpirationTime(date); claims.setNotBeforeMinutesInThePast(1); ...Anda dapat menambahkan parameter kustom ke PAYLOAD JWKS untuk memenuhi kebutuhan bisnis Anda.
Menghasilkan token menggunakan kunci asimetris
Contoh kode:
package org.example; import java.security.PrivateKey; import org.jose4j.json.JsonUtil; import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jws.JsonWebSignature; import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.NumericDate; import org.jose4j.lang.JoseException; import org.jose4j.jwk.RsaJsonWebKey; public class Main { public static void main(String[] args) throws JoseException { // Contoh kunci dalam format JWK String privateKeyJson = "{" + "\"kty\":\"RSA\"," + "\"n\":\"u-8lR9lyRhu8tl4vRxOl7yfshssx5jRstabc9n4Rxrz102Z7TPFYrXBZHgf67Y0d-zx9tWd5j91WZxLHv4K6VWPN7zEWEQNn3vUg76dPHPzVkZJWziFPS1EvS4a2gRZdrE4nPogaQ72WySVC0yUF2fL0NKeOclD__coCFxn4QQjcDXyu_CUbI_FuDcdw267mVjjylAaFvOZHH0pXsV8m5zXlpc2aiemWYQJD9MtWRcoKlexWMkTwbEqW5-NWAl0Uo202ahDA1NiaQ98Ch4nw6g2E1GvwxxHkbvMuZcs5z8F5Ct_w0IPtvY7ngSyEN-WCU40oj-C5NUCy_73FpXXdWQ\"," + "\"e\":\"AQAB\"," + "\"d\":\"Uxg1IqSZazg-Y2AXhVTBrJG5egwD3yZU3qiN0IsDbx0DkFoisG2R6PXg4W9j2n7nv7sKVhgPXrXdyys5mIrDuperaVQJzrHzzlgSHQSb7VQ5Vekfanq95a5avAkvTrpF5raTkYl6G3OLZRqNhnA7Oxe6NEHVsOPxnBQignZgFtiBtCSZY4RVH6Dx4jFfBBNMC9ifyLWLpHut7eczvxI412nBkxgtEjSeFe083NlumO_ZYHbijPcQf5zFWPLEj2EvlgbSwhjc-uSAF4OljAyG_DHZYvztEIGMdxMgBHgwtEvCfzS6PeUgvUR-SB7m_L8z4gjz6TlpSYe3CnZqE69KdQ\"," + "\"p\":\"9mNw8U_GxbcSknueUeFFSU9wKD9E9P2ZO5RP5d7o3qGUXOfbrH_g5GMH3YJiPBDZs_2BYFrAACOY4YM-QTiXWVs4xS3OeD8AdH3wEXR_3DMEkOez3cNq3Jy3ZJabm7IUnPMIWv5gpIHghcx0YTtM5RabSgexLMKh2-6sB466378\"," + "\"q\":\"w0PzXI_8Q5jv15OUq-dV_Z0kp91Icumf6PEERZN4v3i3VolLBnamMiIQiF74ywclKpZmtfOQTfyL41Xj2vbm2Aus6akRsU3NhQlVtIQTzHWUuEQgMIJYDK7--FzEcZORm1qBiEffiWv6U-slyCcLcNDNT-wjMX8BrS4oWHIoCOc\"," + "\"dp\":\"fRRiY76yE_EqVn63Eq4ftGXFdEkaQpzzS1GxderBoTO506hI1rtcedTkS0lDgWa0fjE1mqq3SdrIY8NyuT13Z_9tRHxKkrS5EGpWkyXnOuwTZ1SY9P2dpD1SxJfIizPOTxb5qOf2O81LI-F1O18VXD8rultJUIXGEZaKcpO8vpU\"," + "\"dq\":\"V6EP_vMzD5b707AMYVURFx7Fi3vX_pHvzJcVBrBW2P6wsGouvDjU_tygtMKCPoL3X_RdJbynfwgeMyihd-ujz0L2F2pjYUF8QP7ecoNvays9UbBpDbwBDbge_pCLLDlAeAqW5PT0UXSew7hcnUVAciGSchKT_Kt1siVrv72DT_M\"," + "\"qi\":\"w5fENzxOivbbbUbawAWSuLgWPtvbTKn2XuPzwr_JzZH08-nadWwQFChcvAiCs8V-306TQOh8NfY308QpGDIq-iRfrS7CEePOjRzpHJfsaQ1IFQqzgDZ9VGdJRDlZqRHx0DbqwMlleVKTC6ER6varalbr4lKU-ZPUQLCzj0e4PMs\"" + "}"; JwtClaims claims = new JwtClaims(); claims.setGeneratedJwtId(); // Menghasilkan jti (JWT ID) secara otomatis claims.setIssuedAtToNow(); // Mengatur waktu penerbitan (iat) ke waktu saat ini // Atur waktu kedaluwarsa kurang dari 7 hari NumericDate date = NumericDate.now(); date.addSeconds(120 * 60); // Atur waktu kedaluwarsa menjadi waktu saat ini ditambah 120 menit claims.setExpirationTime(date); claims.setNotBeforeMinutesInThePast(1); // Atur waktu not-before (nbf) menjadi 1 menit sebelumnya // Tambahkan parameter kustom. Semua nilai harus bertipe String. // Atur ID konsumen claims.setClaim("uid", "11215ac069234abcb8944232b79ae711"); JsonWebSignature jws = new JsonWebSignature(); // Atur algoritma enkripsi menjadi RSA-SHA256 jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); // Urai kunci privat dan atur dalam penandatangan PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyJson)).getPrivateKey(); jws.setKey(privateKey); // Atur konten payload jws.setPayload(claims.toJson()); // Hasilkan JWT String jwtResult = jws.getCompactSerialization(); System.out.println("Hasil Token Web JSON yang dihasilkan adalah: \n" + jwtResult); } }Pengaturan kode:
Atur
privateKeyJson, ID konsumen, dan waktu kedaluwarsa. Ini sama seperti pada algoritma enkripsi simetris.Atur algoritma enkripsi. Misalnya,
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256). Algoritma ini harus sesuai dengan yang ada di JWKS.Untuk mengenkripsi data menggunakan algoritma enkripsi kunci asimetris, Anda harus menggunakan kunci privat.
... jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyJson)).getPrivateKey(); jws.setKey(privateKey); ...Anda dapat menambahkan parameter kustom ke
PAYLOADJWT sesuai kebutuhan.
Mengirim permintaan bisnis dari klien ke gerbang
API Gateway berbasis cloud mendukung melewatkan token dalam header. Anda dapat menyesuaikan nama header permintaan dan awalan token. Selama validasi permintaan, kunci dan awalan harus sesuai dengan konfigurasi autentikasi konsumen.
Jika permintaan tidak berisi JWT, kesalahan 401 dikembalikan.
curl http://xxx.hello.com/testJika permintaan berisi JWT yang tidak valid, kesalahan 401 dikembalikan.
curl http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ1'Jika permintaan berisi JWT yang valid tetapi konsumen tidak memiliki izin untuk mengakses API atau entri rute, kesalahan 403 dikembalikan.
# consumer1 tidak diotorisasi untuk entri rute atau API pada path berikut curl 'http://xxx.example.com/test' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
Memverifikasi token di sisi server
Verifikasi token di sisi server melibatkan tiga langkah berikut:
Saat server menerima permintaan pengguna, pertama-tama memeriksa apakah token disertakan. Jika tidak, permintaan ditolak dengan kesalahan 401.
Untuk permintaan yang berisi token, server menggunakan kunci publik dari JWKS yang dikonfigurasi untuk memverifikasi bahwa token valid dan belum kedaluwarsa. Jika token tidak valid atau kedaluwarsa, permintaan ditolak dengan kesalahan 401.
Jika token valid, server kemudian memeriksa apakah konsumen yang diwakili oleh token tersebut diotorisasi untuk mengakses API atau entri rute yang diminta.
Kode kesalahan umum
Kode status HTTP | Pesan kesalahan | Penyebab |
401 | Jwt missing | Header permintaan tidak berisi JWT. |
401 | Jwt expired | JWT telah kedaluwarsa. |
401 | Jwt verification fails | Verifikasi payload JWT gagal. Misalnya, klaim `iss` tidak cocok. |
403 | Access Denied | Tidak memiliki izin untuk mengakses entri rute saat ini. |
Otentikasi AK/SK (HMAC)
Menghasilkan tanda tangan di sisi klien
Alur pembuatan tanda tangan di sisi klien:
Ekstrak string yang akan ditandatangani: Ekstrak data kunci dari permintaan asli untuk membuat string yang akan ditandatangani.
Hasilkan tanda tangan: Gunakan algoritma enkripsi dan Secret Key (SK) yang dikonfigurasi untuk mengenkripsi string yang akan ditandatangani dan menghasilkan tanda tangan.
Tambahkan tanda tangan: Tambahkan semua header terkait tanda tangan ke permintaan HTTP asli untuk membuat permintaan HTTP akhir.
Langkah 1: Ekstrak string yang akan ditandatangani
Klien perlu mengekstrak data kunci dari permintaan HTTP dan menggabungkannya menjadi string yang akan ditandatangani. Format string yang akan ditandatangani yang dihasilkan adalah sebagai berikut:
HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParametersKetujuh bidang ini membentuk seluruh string yang akan ditandatangani. Bidang-bidang dipisahkan oleh line feed (`\n`). Jika bidang `Headers` kosong, jangan tambahkan line feed setelah bidang `Headers`. Untuk semua bidang kosong lainnya, Anda harus tetap mempertahankan line feed. Tanda tangan bersifat case-sensitive. Aturan untuk mengekstrak setiap bidang adalah sebagai berikut:
HTTPMethod: Metode HTTP dalam huruf besar. Misalnya, POST.
Accept: Nilai header `Accept` dalam permintaan. Bidang ini bisa kosong. Anda harus secara eksplisit mengatur header `Accept`. Jika header ini kosong, beberapa klien HTTP menetapkan nilai default
*/*, yang menyebabkan verifikasi tanda tangan gagal.Content-MD5: Nilai header `Content-MD5` dalam permintaan. Bidang ini bisa kosong. Anda harus menghitung header `Content-MD5` hanya jika permintaan memiliki badan yang bukan dalam format form. Kode Java berikut menunjukkan cara menghitung nilai Content-MD5:
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8")));Content-Type: Nilai header `Content-Type` dalam permintaan. Bidang ini bisa kosong.
Date: Nilai header `Date` dalam permintaan. Bidang ini bisa kosong jika konfigurasi
date_offsettidak diaktifkan. Jika diaktifkan, gerbang menggunakan bidang ini untuk verifikasi offset waktu.Headers: Anda dapat memilih header tertentu untuk dimasukkan dalam tanda tangan. Aturan untuk menggabungkan string header adalah sebagai berikut:
Kunci header yang dimasukkan dalam perhitungan tanda tangan diurutkan secara alfabetis lalu digabungkan sebagai berikut.
HeaderKey1 + ":" + HeaderValue1 + "\n"\+ HeaderKey2 + ":" + HeaderValue2 + "\n"\+ ... HeaderKeyN + ":" + HeaderValueN + "\n"
Jika nilai header kosong, gunakan `HeaderKey+":"+"\n"` untuk tanda tangan. Kunci dan titik dua harus dipertahankan.
Daftar kunci header yang dimasukkan dalam tanda tangan, dipisahkan koma, ditempatkan dalam header `X-Ca-Signature-Headers`.
Header berikut tidak dimasukkan dalam perhitungan tanda tangan header: `X-Ca-Signature`, `X-Ca-Signature-Headers`, `Accept`, `Content-MD5`, `Content-Type`, dan `Date`.
PathAndParameters: Bidang ini berisi path dan semua parameter dari query dan form. Strukturnya sebagai berikut:
Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueNPentingKunci pasangan parameter query dan form diurutkan secara alfabetis lalu digabungkan seperti yang ditunjukkan di atas.
Jika tidak ada parameter query atau form, gunakan hanya path. Jangan tambahkan
?.Jika nilai parameter kosong, hanya sertakan kuncinya dalam tanda tangan. Jangan tambahkan tanda sama dengan.
Jika ada parameter array dalam query atau form (kunci sama, nilai berbeda), gunakan nilai pertama untuk perhitungan tanda tangan.
Langkah 2: Enkripsi tanda tangan
Setelah klien mengekstrak data kunci dari permintaan HTTP dan merakit string yang akan ditandatangani, klien harus mengenkripsi string tersebut dan mengkodekan hasilnya untuk menghasilkan tanda tangan akhir. Format enkripsi adalah sebagai berikut, di mana stringToSign adalah string yang akan ditandatangani yang diekstrak, secret adalah Secret Key (SK) dari konfigurasi autentikasi Access Key (AK)/SK, dan sign adalah tanda tangan yang dihasilkan:
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] secretBytes = secret.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA256"));
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = Base64.encodeBase64String(result);Ringkasnya: Kodekan stringToSign menggunakan UTF-8 untuk mendapatkan array byte. Enkripsi array byte dengan algoritma yang ditentukan. Kemudian, kodekan hasilnya menggunakan Base64 untuk menghasilkan tanda tangan akhir.
Langkah 3: Tambahkan tanda tangan
Klien harus menyertakan empat header berikut dalam permintaan HTTP yang dikirim ke API Gateway untuk verifikasi tanda tangan:
x-ca-key: Nilainya adalah Access Key (AK) dari konfigurasi autentikasi AK/SK.
x-ca-signature-method: Algoritma tanda tangan. Nilai yang valid adalah `HmacSHA256` atau `HmacSHA1`. Ini opsional. Nilai default adalah `HmacSHA256`.
x-ca-signature-headers: Daftar kunci header yang ditandatangani, dipisahkan koma. Ini opsional.
x-ca-signature: Tanda tangan. Ini wajib.
Memverifikasi tanda tangan di sisi server
Tinjauan verifikasi tanda tangan klien di sisi server:
Ekstrak string yang akan ditandatangani: Ekstrak data kunci dari permintaan yang diterima untuk membuat string yang akan ditandatangani.
Ekstrak AK: Baca AK dari permintaan yang diterima dan gunakan untuk menemukan SK yang sesuai.
Hitung tanda tangan: Gunakan algoritma enkripsi dan SK untuk mengenkripsi string yang akan ditandatangani dan menghasilkan tanda tangan.
Verifikasi tanda tangan: Baca tanda tangan klien dari permintaan yang diterima dan bandingkan dengan tanda tangan yang dihasilkan server untuk memastikan konsistensi.
Penanganan kesalahan
Jika gerbang gagal memverifikasi tanda tangan, gerbang mengembalikan string yang akan ditandatangani dari sisi server ke klien dalam header X-Ca-Error-Message pada respons HTTP. Anda dapat mengidentifikasi masalah dengan membandingkan string yang akan ditandatangani dari sisi klien dengan string yang akan ditandatangani dari sisi server. Jika nilai string yang akan ditandatangani dari klien dan server sama, periksa SK yang digunakan untuk perhitungan tanda tangan. Karena header HTTP tidak dapat berisi line feed, line feed dalam string yang akan ditandatangani diganti dengan #, seperti yang ditunjukkan di bawah ini:
X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json##X-Ca-Key:200000#X-Ca-Timestamp:1589458000000#/app/v1/config/keys?keys=TEST`Kode kesalahan terkait
Kode status HTTP | Pesan kesalahan | Penyebab |
401 | Invalid Key | Header `x-ca-key` tidak disediakan atau tidak valid. |
401 | Empty Signature | Header `x-ca-signature` tidak disediakan. |
400 | Invalid Signature | Tanda tangan dalam header `x-ca-signature` tidak cocok dengan tanda tangan yang dihitung oleh server. |
400 | Invalid Content-MD5 | Header `content-md5` salah. |
400 | Invalid Date | Offset waktu yang dihitung dari header `date` melebihi `date_offset` yang dikonfigurasi. |
413 | Request Body Too Large | Badan permintaan melebihi batas ukuran 32 MB. |
413 | Payload Too Large | Badan permintaan melebihi konfigurasi global `DownstreamConnectionBufferLimits`. |
403 | Unauthorized Consumer | Pemanggil tidak memiliki izin akses. |
Kode contoh (Go)
go
package main
import (
"bytes"
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/base64"
"fmt"
"io"
"net/http"
"strings"
"time"
)
func generateHMACSignature(toSign string, key string) (string, error) {
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(toSign))
return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil
}
func test(accessKey, secretKey string) {
body := `{"hello":"world"}`
h := md5.New()
h.Write([]byte(body))
payload := base64.StdEncoding.EncodeToString(h.Sum(nil))
headers := map[string]string{
"accept": "application/json",
"content-type": "application/json",
"date": time.Now().Format("2006-01-02 15:04:05"),
"x-ca-key": accessKey,
"foo": "bar",
"x-ca-signature-headers": "foo",
"content-md5": payload,
}
sts := strings.Join([]string{"POST", headers["accept"], headers["content-md5"], headers["content-type"], headers["date"], "foo:bar", "/post"}, "\n")
fmt.Printf("String yang akan ditandatangani adalah: %s\n", strings.ReplaceAll(sts, "\n", "#"))
sign, _ := generateHMACSignature(sts, secretKey)
fmt.Printf("String yang ditandatangani adalah: %s\n", sign)
headers["x-ca-signature"] = sign
req, _ := http.NewRequest("POST", "http://localhost:8080/post", bytes.NewBufferString(body))
for k, v := range headers {
req.Header.Add(k, v)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("kesalahan membaca badan")
}
defer resp.Body.Close()
fmt.Println("Header adalah sebagai berikut:")
for k, v := range resp.Header {
// Jika perhitungan tanda tangan gagal, header respons X-Ca-Error-Message akan berisi string yang akan ditandatangani yang dihitung oleh server. Anda dapat menggunakan ini untuk memecahkan masalah.
fmt.Printf(" %s: %s\n", k, v)
}
respBody, _ := io.ReadAll(resp.Body)
fmt.Println(string(respBody))
}
func main() {
test("appKey", "appSecret")
}
Otentikasi kunci API
Permintaan diverifikasi berdasarkan sumber kredensial yang dikonfigurasi. Prosesnya serupa untuk API dan entri rute. Contoh berikut menggunakan entri rute.
Terdapat tiga jenis utama sumber kredensial untuk kunci API:
Sumber kredensial default: `Authorization: Bearer `.
Header Kustom: Masukkan nama parameter header.
Parameter kueri kustom: Masukkan nama parameter kueri.
Sumber kredensial default
Asumsikan permintaan berikut cocok dengan entri rute `abc`. Atur kunci API dalam header permintaan HTTP `Authorization` dan tambahkan awalan `Bearer`. Perhatikan bahwa terdapat spasi antara `Bearer` dan kunci API.
curl http://xxx.test.com/test -H 'x-api-key: Bearer 2bda943c-ba2b-11ec-ba07-00163e1250b5'Setel Kunci API di Header Permintaan HTTP
curl http://xxx.test.com/test -H 'x-api-key: Bearer 2bda943c-ba2b-11ec-ba07-00163e1250b5'Sumber header kustom
Asumsikan permintaan berikut cocok dengan entri rute `abc`, dan kunci API diatur dalam header permintaan HTTP kustom.
Jika entri rute tidak memiliki kebijakan autentikasi dan otorisasi konsumen yang diaktifkan, akses ditolak dengan kesalahan 401.
curl http://xxx.test.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5Jika entri rute memiliki kebijakan autentikasi dan otorisasi konsumen yang diaktifkan tetapi tidak diotorisasi, kesalahan 403 dikembalikan.
curl http://xxx.test.com/test -H 'x-api-key: 2bda943c-ba2b-11ec-ba07-00163e1250b5'
Parameter kueri kustom
Asumsikan permintaan berikut cocok dengan entri rute `abc`, dan kunci API diatur dalam parameter kueri URL.
Jika entri rute tidak memiliki kebijakan autentikasi dan otorisasi konsumen yang diaktifkan, akses ditolak dengan kesalahan 401.
curl http://xxx.test.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5Jika entri rute memiliki kebijakan autentikasi dan otorisasi konsumen yang diaktifkan tetapi tidak diotorisasi, kesalahan 403 dikembalikan.
curl http://xxx.test.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5
Kode kesalahan terkait
Kode Status HTTP | Pesan Kesalahan | Penyebab |
401 | Key authentication check failed. Multiple API keys were found in the request. | Anda dapat meminta beberapa kunci API. |
401 | Key authentication check failed. No API key was found in the request. | Permintaan tidak berisi kunci API. |
401 | Key authentication check failed. The API key is invalid. | Kunci API tidak diotorisasi untuk mengakses sumber daya. |
403 | Key authentication check failed. The consumer is unauthorized. | Konsumen tidak memiliki izin akses yang diperlukan. |
Referensi
Untuk informasi lebih lanjut, lihat Manajemen otorisasi.