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 |
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. |
Konfigurasi otorisasi dan konfigurasi otentikasi tidak dapat berkoeksistensi dalam satu aturan.
Untuk permintaan yang telah diautentikasi, bidang
X-Mse-Consumerditambahkan 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-2Terapkan konfigurasi plug-in berikut ke rute route-a dan route-b:
allow:
- consumer1Terapkan konfigurasi plug-in berikut ke nama domain *.example.com dan test.com:
allow:
- consumer2Dalam contoh ini, rute
route-adanroute-badalah rute yang ditentukan saat pembuatan rute gateway. Jika permintaan klien cocok dengan salah satu rute, pemanggil dengannameconsumer1diizinkan untuk mengakses gateway. Pemanggil lainnya tidak diizinkan mengakses gateway.Dalam contoh ini, nama domain
*.example.comdantest.comdigunakan untuk mencocokkan nama domain dalam permintaan. Jika permintaan klien cocok dengan salah satu nama domain, pemanggil dengannameconsumer2diizinkan 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-2Mekanisme 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:
Ekstrak data kunci dari permintaan asli dan hasilkan string tanda tangan.
Gunakan algoritma enkripsi dan
secretyang dikonfigurasi untuk mengenkripsi string tanda tangan dan hasilkan tanda tangan.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
PathAndParametersBidang-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_offsettidak 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
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=123456789String 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=xiaomingHitung 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=123456789Verifikasi Tanda Tangan di Sisi Server
Proses
Untuk memverifikasi tanda tangan yang diterima dari klien, server melakukan langkah-langkah berikut:
Ekstrak data kunci dari permintaan untuk mendapatkan string tanda tangan.
Baca
keydari permintaan dan gunakankeyuntuk mendapatkansecret.Gunakan algoritma enkripsi dan
secretuntuk mengenkripsi string tanda tangan untuk mendapatkan tanda tangan.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. |
Jika Anda meningkatkan nilai DownstreamConnectionBufferLimits, penggunaan memori gateway akan meningkat secara signifikan. Berhati-hatilah saat melakukan operasi ini.