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 detail tentang dukungan untuk CBOR Web Tokens (CWT) di CloudFront Fungsi Anda, yang memungkinkan otentikasi dan otorisasi berbasis token yang aman di Lokasi Edge. CloudFront Dukungan ini disediakan sebagai modul, dapat diakses di CloudFront Fungsi Anda.

Untuk menggunakan modul ini, buat CloudFront Function 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 dengan benar dan dapat diidentifikasi (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 menerjemahkan dan memvalidasi token CWT menggunakan kunci yang ditentukan. Jika validasi berhasil, ia mengembalikan token CWT yang diterjemahkan. Jika tidak, itu akan menimbulkan kesalahan. Harap dicatat bahwa fungsi ini tidak melakukan validasi pada set klaim.

Permintaan

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

Token yang dikodekan untuk validasi. Ini pasti JavaScript Buffer.

HandlerContext (Diperlukan)

JavaScript Objek 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 berhasil divalidasi, respon dari fungsi adalah CWTObject dalam format berikut. Setelah diterjemahkan, semua kunci klaim direpresentasikan sebagai string.

CWTObject { protectedHeaders, unprotectedHeaders, payload }

Contoh - Validasi token dengan anak dikirim sebagai bagian dari token

Contoh ini menunjukkan validasi token CWT, di mana anak diekstraksi dari header. Anak itu kemudian diteruskan ke CloudFront Fungsi 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 JavaScript Object 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 dapat berupa string atau JavaScript Buffer.

payload (Wajib)

Payload token untuk pengkodean. Muatan harus dalam CWTObject format.

Respons

Mengembalikan JavaScript Buffer yang berisi token 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 : Segarkan 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; }