View a markdown version of this page

Dukungan CWT untuk Fungsi CloudFront - Amazon CloudFront

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Dukungan CWT untuk Fungsi CloudFront

Bagian ini memberikan rincian tentang dukungan untuk CBOR Web Token (CWT) di CloudFront Functions Anda, yang memungkinkan otentikasi dan otorisasi berbasis token aman di CloudFront Lokasi Edge. Dukungan ini disediakan sebagai modul, dapat diakses di CloudFront Fungsi Anda.

Untuk menggunakan modul ini, buat CloudFront Fungsi menggunakan JavaScript runtime 2.0 dan sertakan pernyataan berikut di baris pertama kode fungsi:

import cf from 'cloudfront';

Metode yang terkait dengan modul ini dapat diakses melalui (di mana * adalah wildcard yang mewakili berbagai fungsi yang ada dalam modul):

cf.cwt.*

Untuk informasi selengkapnya, lihat JavaScript fitur runtime 2.0 untuk Fungsi CloudFront.

Saat ini, modul hanya mendukung struktur MAC0 dengan algoritma HS256 (HMAC-SHA256) dengan batas 1KB untuk ukuran token maksimum.

Struktur token

Bagian ini mencakup struktur token yang diharapkan oleh modul CWT. Modul mengharapkan token ditandai dan diidentifikasi dengan benar (misalnya COSE MAC0). Selain itu, untuk struktur token, modul mengikuti standar yang ditetapkan oleh CBOR Object Signing and Encryption (COSE) [RFC 8152].

( // CWT Tag (Tag value: 61) --- optional ( // COSE MAC0 Structure Tag (Tag value: 17) --- required [ protectedHeaders, unprotectedHeaders, payload, tag, ] ) )
contoh: CWT menggunakan struktur COSE MAC0
61( // CWT tag 17( // COSE_MAC0 tag [ { // Protected Headers 1: 4 // algorithm : HMAC-256-64 }, { // Unprotected Headers 4: h'53796d6d6574726963323536' // kid : Symmetric key id }, { // Payload 1: "https://iss.example.com", // iss 2: "exampleUser", // sub 3: "https://aud.example.com", // aud 4: 1444064944, // exp 5: 1443944944, // nbf 6: 1443944944, // iat }, h'093101ef6d789200' // tag ] ) )
catatan

Tag CWT bersifat opsional saat menghasilkan token. Namun, tag struktur COSE diperlukan.

Metode validateToken ()

Fungsi memecahkan kode dan memvalidasi token CWT menggunakan kunci yang ditentukan. Jika validasi berhasil, ia mengembalikan token CWT yang didekodekan. Jika tidak, itu menimbulkan kesalahan. Harap dicatat bahwa fungsi ini tidak melakukan validasi pada kumpulan klaim.

Permintaan

cf.cwt.validateToken(token, handlerContext{key})
Parameter
token (wajib)

Token yang dikodekan untuk validasi. Ini harus menjadi JavaScript buffer.

HandlerContext (Diperlukan)

Ob JavaScript jek yang menyimpan konteks untuk panggilan validateToken. Saat ini, hanya properti kunci yang didukung.

kunci (Diperlukan)

Kunci rahasia untuk perhitungan intisari pesan. Dapat disediakan baik sebagai string atau JavaScript Buffer.

Respons

Ketika validateToken() metode mengembalikan token yang berhasil divalidasi, respons dari fungsi adalah a CWTObject dalam format berikut. Setelah diterjemahkan, semua kunci klaim direpresentasikan sebagai string.

CWTObject { protectedHeaders, unprotectedHeaders, payload }

Contoh - Validasi token dengan anak yang dikirim sebagai bagian dari token

Contoh ini menunjukkan validasi token CWT, di mana anak diekstraksi dari header. Anak itu kemudian diteruskan ke CloudFront Functions KeyValueStore untuk mengambil kunci rahasia yang digunakan untuk memvalidasi token.

import cf from 'cloudfront' const CwtClaims = { iss: 1, aud: 3, exp: 4 } async function handler(event) { try { let request = event.request; let encodedToken = request.headers['x-cwt-token'].value; let kid = request.headers['x-cwt-kid'].value; // Retrieve the secret key from the kvs let secretKey = await cf.kvs().get(kid); // Now you can use the secretKey to decode & validate the token. let tokenBuffer = Buffer.from(encodedToken, 'base64url'); let handlerContext = { key: secretKey, } try { let cwtObj = cf.cwt.validateToken(tokenBuffer, handlerContext); // Check if token is expired const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds if (cwtObj[CwtClaims.exp] && cwtObj[CwtClaims.exp] < currentTime) { return { statusCode: 401, statusDescription: 'Token expired' }; } } catch (error) { return { statusCode: 401, statusDescription: 'Invalid token' }; } } catch (error) { return { statusCode: 402, statusDescription: 'Token processing failed' }; } return request; }

metode generateToken ()

Fungsi ini menghasilkan token CWT baru menggunakan pengaturan payload dan konteks yang disediakan.

Permintaan

cf.cwt.generateToken(generatorContext, payload)
Parameter
GeneratorContext (Diperlukan)

Ini Ob JavaScript jek yang digunakan sebagai konteks untuk menghasilkan token dan berisi pasangan nilai kunci berikut:

CWTTag (Opsional)

Nilai ini adalah boolean, yang jika true menentukan cwtTag harus ditambahkan.

CoseTag (Diperlukan)

Menentukan jenis tag COSE. Saat ini hanya mendukungMAC0.

kunci (Diperlukan)

Kunci rahasia untuk menghitung intisari pesan. Nilai ini bisa berupa string atau JavaScript Buffer.

muatan (Diperlukan)

Payload token untuk pengkodean. Muatan harus dalam CWTObject format.

Respons

Mengembalikan JavaScript Buffer yang berisi token yang dikodekan.

contoh: Menghasilkan token CWT
import cf from 'cloudfront'; const CwtClaims = { iss: 1, sub: 2, exp: 4 }; const CatClaims = { catu: 401, catnip: 402, catm: 403, catr: 404 }; const Catu = { host: 1, path: 2, ext: 3 }; const CatuMatchTypes = { prefix_match: 1, suffix_match: 2, exact_match: 3 }; const Catr = { renewal_method: 1, next_renewal_time: 2, max_uses: 3 }; async function handler(event) { try { const response = { statusCode: 200, statusDescription: 'OK', headers: {} }; const commonAccessToken = { protected: { 1: "5", }, unprotected: {}, payload: { [CwtClaims.iss]: "cloudfront-documentation", [CwtClaims.sub]: "cwt-support-on-cloudfront-functions", [CwtClaims.exp]: 1740000000, [CatClaims.catu]: { [Catu.host]: { [CatuMatchTypes.suffix_match]: ".cloudfront.net" }, [Catu.path]: { [CatuMatchTypes.prefix_match]: "/media/live-stream/cf-4k/" }, [Catu.ext]: { [CatuMatchTypes.exact_match]: [ ".m3u8", ".ts", ".mpd" ] } }, [CatClaims.catnip]: [ "[IP_ADDRESS]", "[IP_ADDRESS]" ], [CatClaims.catm]: [ "GET", "HEAD" ], [CatClaims.catr]: { [Catr.renewal_method]: "header_renewal", [Catr.next_renewal_time]: 1750000000, [Catr.max_uses]: 5 } } }; if (!request.headers['x-cwt-kid']) { throw new Error('Missing x-cwt-kid header'); } const kid = request.headers['x-cwt-kid'].value; const secretKey = await cf.kvs().get(kid); if (!secretKey) { throw new Error('Secret key not found for provided kid'); } try { const genContext = { cwtTag: true, coseTag: "MAC0", key: secretKey }; const tokenBuffer = cf.cwt.generateToken(commonAccessToken, genContext); response.headers['x-generated-cwt-token'] = { value: tokenBuffer.toString('base64url') }; return response; } catch (tokenError) { return { statusCode: 401, statusDescription: 'Could not generate the token' }; } } catch (error) { return { statusCode: 402, statusDescription: 'Token processing failed' }; } }
contoh: Refresh token berdasarkan beberapa logika
import cf from 'cloudfront' const CwtClaims = { iss: 1, aud: 3, exp: 4 } async function handler(event) { try { let request = event.request; let encodedToken = request.headers['x-cwt-token'].value; let kid = request.headers['x-cwt-kid'].value; let secretKey = await cf.kvs().get(kid); // Retrieve the secret key from the kvs // Now you can use the secretKey to decode & validate the token. let tokenBuffer = Buffer.from(encodedToken, 'base64url'); let handlerContext = { key: secretKey, } try { let cwtJSON = cf.cwt.validateToken(tokenBuffer, handlerContext); // Check if token is expired const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds if (cwtJSON[CwtClaims.exp] && cwtJSON[CwtClaims.exp] < currentTime) { // We can regnerate the token and add 8 hours to the expiry time cwtJSON[CwtClaims.exp] = Math.floor(Date.now() / 1000) + (8 * 60 * 60); let genContext = { coseTag: "MAC0", key: secretKey } let newTokenBuffer = cf.cwt.generateToken(cwtJSON, genContext); request.headers['x-cwt-regenerated-token'] = newTokenBuffer.toString('base64url'); } } catch (error) { return { statusCode: 401, statusDescription: 'Invalid token' }; } } catch (error) { return { statusCode: 402, statusDescription: 'Token processing failed' }; } return request; }