All Products
Search
Document Center

API Gateway:hmac-auth

Last Updated:Jun 28, 2025

Plug-in hmac-auth digunakan untuk menghasilkan tanda tangan yang tidak dapat dipalsukan untuk permintaan HTTP berdasarkan algoritma Hash-based Message Authentication Code (HMAC). Tanda tangan ini digunakan untuk otentikasi identitas. Topik ini menjelaskan cara mengonfigurasi plug-in hmac-auth.

Jenis Plug-in

Plug-in untuk otentikasi dan otorisasi.

Bidang

Konfigurasi Otentikasi

Bidang

Tipe Data

Diperlukan

Nilai Default

Deskripsi

konsumen

array of object

Ya

-

Pemanggil layanan. Bidang ini digunakan untuk mengotentikasi permintaan.

date_offset

number

Tidak

-

Offset waktu maksimum klien dalam detik. Sistem menggunakan bidang ini untuk mengurai Waktu Universal Terkoordinasi (UTC) klien dari header Date permintaan untuk mencegah serangan pemutaran ulang. Jika parameter ini tidak dikonfigurasi, sistem tidak akan memverifikasi waktu UTC klien.

global_auth

array of string

Tidak (Diperlukan hanya untuk konfigurasi tingkat instance)

-

Bidang ini hanya dapat dikonfigurasi pada tingkat instance. Jika bidang ini diatur ke true, mekanisme otentikasi berlaku secara global. Jika bidang ini diatur ke false, mekanisme otentikasi hanya berlaku untuk nama domain dan rute yang telah dikonfigurasi. Jika bidang ini tidak dikonfigurasi, mekanisme otentikasi berlaku secara global hanya ketika tidak ada nama domain dan rute yang dikonfigurasi. Hal ini mempertimbangkan kebiasaan pengguna lama.

Tabel berikut menjelaskan bidang-bidang dalam konsumen.

Bidang

Tipe Data

Diperlukan

Nilai Default

Deskripsi

key

string

Ya

-

Kunci akses konsumen.

secret

string

Ya

-

Rahasia yang digunakan untuk menghasilkan tanda tangan.

name

string

Ya

-

Nama konsumen.

(Opsional) Konfigurasi Otorisasi

Bidang

Tipe Data

Diperlukan

Nilai Default

Deskripsi

allow

array of string

Tidak (Diperlukan untuk konfigurasi non-tingkat instance)

-

Anda hanya dapat mengonfigurasi bidang ini pada granularitas halus seperti rute atau nama domain. Untuk permintaan yang memenuhi kondisi pencocokan, Anda dapat mengonfigurasi konsumen yang diizinkan untuk akses. Ini mengimplementasikan kontrol izin halus.

Penting
  • Konfigurasi otorisasi dan konfigurasi otentikasi tidak dapat berkoeksistensi dalam satu aturan.

  • Untuk permintaan yang telah diautentikasi, bidang X-Mse-Consumer ditambahkan ke header permintaan untuk mengidentifikasi nama pemanggil.

Contoh

Mengonfigurasi otentikasi secara global dan mengonfigurasi otorisasi untuk rute

Berikut adalah contoh cara mengaktifkan otentikasi berbasis plug-in hmac-auth untuk rute atau nama domain tertentu dari gateway. Bidang key harus unik.

Terapkan konfigurasi plug-in berikut pada tingkat instance:

global_auth: false
konsumen: 
- key: appKey-example-1
  secret: appSecret-example-1
  name: consumer-1
- key: appKey-example-2
  secret: appSecret-example-2
  name: consumer-2

Terapkan konfigurasi plug-in berikut ke rute route-a dan route-b:

allow:
- consumer1

Terapkan konfigurasi plug-in berikut ke nama domain *.example.com dan test.com:

allow:
- consumer2
Catatan
  • Dalam contoh ini, rute route-a dan route-b adalah rute yang ditentukan saat pembuatan rute gateway. Jika permintaan klien cocok dengan salah satu rute, pemanggil dengan name consumer1 diizinkan untuk mengakses gateway. Pemanggil lainnya tidak diizinkan mengakses gateway.

  • Dalam contoh ini, nama domain *.example.com dan test.com digunakan untuk mencocokkan nama domain dalam permintaan. Jika permintaan klien cocok dengan salah satu nama domain, pemanggil dengan name consumer2 diizinkan untuk mengakses gateway. Pemanggil lainnya tidak diizinkan mengakses gateway.

Aktifkan plug-in traffic-tag untuk gateway

global_auth: true
konsumen: 
- key: appKey-example-1
  secret: appSecret-example-1
  name: consumer-1
- key: appKey-example-2
  secret: appSecret-example-2
  name: consumer-2

Mekanisme Tanda Tangan

Persiapan Konfigurasi

Anda harus mengonfigurasi pengaturan kredensial berikut yang diperlukan untuk menghasilkan dan memvalidasi tanda tangan.

  • key: digunakan dalam header permintaan x-ca-key.

  • secret: digunakan untuk menghasilkan tanda tangan permintaan.

Hasilkan Tanda Tangan di Klien

Proses

Untuk menghasilkan tanda tangan, klien melakukan langkah-langkah berikut:

  1. Ekstrak data kunci dari permintaan asli dan hasilkan string tanda tangan.

  2. Gunakan algoritma enkripsi dan secret yang dikonfigurasi untuk mengenkripsi string tanda tangan dan hasilkan tanda tangan.

  3. Tambahkan semua header yang terkait dengan tanda tangan ke permintaan HTTP asli untuk mendapatkan permintaan HTTP akhir.

Ekstrak String Tanda Tangan

Untuk menghasilkan tanda tangan, klien perlu mengekstrak data kunci dari permintaan HTTP dan menggabungkan data kunci menjadi string tanda tangan. String tanda tangan memiliki format berikut:

HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParameters

Bidang-bidang sebelumnya membentuk string tanda tangan dan dipisahkan oleh \n. Jika Anda meninggalkan bidang Headers kosong, \n tidak diperlukan. Jika Anda meninggalkan bidang lainnya kosong, \n harus tetap dipertahankan. Tanda tangan bersifat peka huruf besar-kecil.

Aturan untuk mengekstrak setiap bidang:

  • HTTPMethod: metode HTTP yang digunakan untuk mengirim permintaan, seperti POST. Nilai bidang ini dalam huruf besar.

  • Accept: nilai header Accept dalam permintaan. Anda dapat meninggalkan header Accept kosong. Kami sarankan Anda secara eksplisit menentukan header Accept dalam permintaan. Jika header Accept kosong, beberapa klien HTTP menggunakan nilai default */* untuk Accept. Akibatnya, verifikasi tanda tangan gagal.

  • Content-MD5: nilai header Content-MD5, yang dapat dibiarkan kosong. Nilai ini dihitung hanya jika permintaan berisi body tipe non-Form. Contoh berikut digunakan untuk menghitung nilai header Content-MD5 dalam format Java:

    String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8")));
  • Content-Type: nilai header Content-Type, yang dapat dibiarkan kosong.

  • Date: nilai header Date, yang digunakan untuk verifikasi offset waktu. Anda dapat meninggalkan bidang ini kosong jika date_offset tidak ditentukan.

  • Headers: Anda dapat menentukan header untuk menghitung tanda tangan. Saat Anda menggabungkan string tanda tangan, aturan berikut berlaku:

    • Kunci header pertama kali diurutkan secara alfabetis dan kemudian digabungkan berdasarkan aturan berikut:

      HeaderKey1 + ":" + HeaderValue1 + "\n"\+
      HeaderKey2 + ":" + HeaderValue2 + "\n"\+
      ...
      HeaderKeyN + ":" + HeaderValueN + "\n"
    • Jika nilai header kosong, gunakan HeaderKey + ":" + "\n" untuk tanda tangan. Anda harus mempertahankan kunci header dan titik dua (:).

    • Kunci header yang digunakan untuk tanda tangan dipisahkan oleh koma (,) dan ditempatkan di header dengan kunci X-Ca-Signature-Headers.

    • Anda tidak dapat menggunakan header berikut untuk menghitung tanda tangan: X-Ca-Signature, X-Ca-Signature-Headers, Accept, Content-MD5, Content-Type, dan Date.

  • Bidang PathAndParameters berisi semua jalur, query, dan parameter formulir.

    Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
Catatan
  • Kunci parameter query dan formulir pertama kali diurutkan secara alfabetis dan kemudian digabungkan dengan metode sebelumnya.

  • Jika parameter query dan formulir dibiarkan kosong, Anda dapat menggunakan parameter jalur tanpa perlu menambahkan informasi tanda tangan.

  • Jika beberapa parameter query dan formulir adalah parameter array dengan kunci yang sama tetapi nilai berbeda, nilai pertama digunakan untuk perhitungan tanda tangan.

Contoh Ekstraksi String Tanda Tangan

Permintaan HTTP awal:

POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789

String tanda tangan yang dihasilkan:

POST
application/json; charset=utf-8
application/x-www-form-urlencoded; charset=utf-8
Wed, 09 May 2018 13:30:29 GMT+00:00
x-ca-key:203753385
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-signature-method:HmacSHA256
x-ca-timestamp:1525872629832
/http2test/test?param1=test&password=123456789&username=xiaoming

Hitung Tanda Tangan

Setelah klien mengekstrak data kunci dari permintaan HTTP dan menghasilkan string tanda tangan, klien perlu mengenkripsi dan mengkodekan string tanda tangan untuk membentuk tanda tangan akhir.

Dalam proses enkripsi, stringToSign menentukan string tanda tangan yang diekstrak, secret ditentukan dalam konfigurasi plug-in, dan sign menentukan tanda tangan akhir.

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

Singkatnya, stringToSign didekodekan menjadi larik byte menggunakan UTF-8. Larik byte dienkripsi menggunakan algoritma enkripsi dan kemudian dikodekan menggunakan algoritma Base64 untuk menghasilkan tanda tangan.

Tambahkan Tanda Tangan

Klien harus menyertakan header berikut dalam permintaan yang dikirim ke Cloud-native API Gateway untuk verifikasi tanda tangan:

  • x-ca-key: AppKey, yang diperlukan.

  • x-ca-signature-method: algoritma tanda tangan, yang opsional. Nilai valid: HmacSHA256 dan HmacSHA1. Nilai default: HmacSHA256.

  • x-ca-signature-headers: kumpulan kunci untuk semua header tanda tangan, yang opsional. Kunci dipisahkan oleh koma (,).

  • x-ca-signature: tanda tangan, yang diperlukan.

Contoh berikut menunjukkan permintaan HTTP dengan tanda tangan:

POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-key:203753385
x-ca-signature-method:HmacSHA256
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=
content-length:33
username=xiaoming&password=123456789

Verifikasi Tanda Tangan di Sisi Server

Proses

Untuk memverifikasi tanda tangan yang diterima dari klien, server melakukan langkah-langkah berikut:

  1. Ekstrak data kunci dari permintaan untuk mendapatkan string tanda tangan.

  2. Baca key dari permintaan dan gunakan key untuk mendapatkan secret.

  3. Gunakan algoritma enkripsi dan secret untuk mengenkripsi string tanda tangan untuk mendapatkan tanda tangan.

  4. Baca tanda tangan sisi klien dari permintaan dan bandingkan tanda tangan sisi server dengan tanda tangan sisi klien.

Perbaiki Kesalahan Tanda Tangan

Jika verifikasi tanda tangan gagal, sistem menambahkan string tanda tangan sisi server (StringToSign) ke header respons HTTP yang dikembalikan ke klien. Kuncinya adalah X-Ca-Error-Message. Anda dapat mengidentifikasi kesalahan saat membandingkan string tanda tangan sisi klien (StringToSign) dengan string tanda tangan sisi server.

Jika kedua nilai tersebut sama, periksa AppSecret yang digunakan untuk perhitungan tanda tangan.

Header HTTP tidak mendukung jeda baris. Jeda baris dalam string tanda tangan (StringToSign) diganti dengan tanda pagar (#).

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

Kode status HTTP

Pesan Kesalahan

Penyebab

400

Invalid Signature.

Header permintaan x-ca-signature berisi tanda tangan yang tidak sesuai dengan tanda tangan yang dihitung server.

400

Invalid Content-MD5.

Header permintaan content-md5 tidak valid.

400

Invalid Date.

Offset waktu yang dihitung berdasarkan header permintaan date melebihi date_offset yang dikonfigurasi.

401

Invalid Key.

Header permintaan x-ca-key tidak disediakan atau tidak valid.

401

Empty Signature.

Header permintaan x-ca-signature tidak berisi tanda tangan.

403

Unauthorized Consumer.

Pemanggil permintaan tidak memiliki izin akses.

413

Request Body Too Large.

Ukuran body permintaan melebihi 32 MB.

413

Payload Too Large.

Body permintaan melebihi nilai DownstreamConnectionBufferLimits yang dikonfigurasi untuk gateway. Anda dapat meningkatkan nilai DownstreamConnectionBufferLimits di halaman konfigurasi parameter.

Catatan

Jika Anda meningkatkan nilai DownstreamConnectionBufferLimits, penggunaan memori gateway akan meningkat secara signifikan. Berhati-hatilah saat melakukan operasi ini.