Cara: Memvalidasi pengguna yang membuat kontainer

Saat Anda membuat kontainer di Azure Fluid Relay, JWT yang disediakan oleh ITokenProvider untuk permintaan pembuatan hanya dapat digunakan sekali. Setelah membuat kontainer, klien harus menghasilkan JWT baru yang berisi ID dokumen (yang benar-benar ID kontainer) yang disediakan oleh layanan pada waktu pembuatan. Jika aplikasi memiliki layanan otorisasi yang mengelola kontrol akses kontainer, aplikasi perlu mengetahui siapa yang membuat kontainer dengan ID tertentu untuk mengotorisasi pembuatan JWT baru untuk akses ke kontainer tersebut.

Menginformasikan layanan otorisasi saat kontainer dibuat

Aplikasi dapat mengikat ke dalam siklus hidup pembuatan kontainer dengan menerapkan metode documentPostCreateCallback() publik dalam metode TokenProvider. (Nama fungsi ini bisa membingungkan. Ini benar-benar panggilan balik untuk pembuatan kontainer pos.) Panggilan balik ini akan dipicu langsung setelah membuat kontainer, sebelum klien meminta JWT baru, ia perlu mendapatkan izin baca/tulis ke kontainer yang dibuat.

documentPostCreateCallback() Menerima dua parameter: 1) ID kontainer yang dibuat (juga disebut "ID dokumen") dan 2) JWT yang ditandatangani oleh layanan tanpa cakupan izin. Layanan otorisasi dapat memverifikasi JWT yang diberikan dan menggunakan informasi di JWT untuk memberikan izin pengguna yang benar untuk kontainer yang baru dibuat.

Membuat titik akhir untuk panggilan balik pembuatan kontainer Anda

Contoh di bawah ini adalah Fungsi Azure berdasarkan contoh dalam Cara: Menulis TokenProvider dengan Azure Function.

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ITokenClaims, IUser } from "@fluidframework/protocol-definitions";
import * as jwt from "jsonwebtoken";

// NOTE: retrieve the key from a secure location.
const key = "myTenantKey";

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    const token = (req.query.token || (req.body && req.body.token)) as string;
    const documentId = (req.query.documentId || (req.body && req.body.documentId)) as string;

    if (!token) {
        context.res = {
            status: 400,
            body: "No token provided in request",
        };
        return;
    }
    if (!documentId) {
        context.res = {
            status: 400,
            body: "No documentId provided in request",
        };
        return;
    }
    
    const claims = jwt.decode(token) as ITokenClaims;
    if (!claims) {
        context.res = {
            status: 403,
            body: "Missing token claims",
        };
        return;
    }

    const tenantId = claims.tenantId;
    if (!claims) {
        context.res = {
            status: 400,
            body: "No tenantId provided in token claims",
        };
        return;
    }
    if (!key) {
        context.res = {
            status: 404,
            body: `No key found for the provided tenantId: ${tenantId}`,
        };
        return;
    }
    try {
        jwt.verify(token, key);
    } catch (e) {
        if (e instanceof jwt.TokenExpiredError) {
            context.res = {
                status: 401,
                body: `Token is expired`,
            };
            return
        }
        context.res = {
            status: 403,
            body: `Token signed with invalid key`,
        }
        return;
    }

    const user: IUser = claims.user;
    // Pseudo-function: implement according to your needs
    giveUserPermissionsForContainer(documentId, user);

    context.res = {
        status: 200,
        body: "OK",
    };
};

export default httpTrigger;

Menerapkan documentPostCreateCallback

Contoh implementasi di bawah ini memperluas AzureFunctionTokenProvider dan menggunakan pustaka axios untuk membuat permintaan HTTP ke Azure Function yang digunakan untuk menghasilkan token.

import { AzureFunctionTokenProvider, AzureMember } from "@fluidframework/azure-client";
import axios from "axios";

/**
 * Token Provider implementation for connecting to an Azure Function endpoint for
 * Azure Fluid Relay token resolution.
 */
export class AzureFunctionTokenProviderWithContainerCreateCallback extends AzureFunctionTokenProvider {
    /**
     * Creates a new instance using configuration parameters.
     * @param azFunctionUrl - URL to Azure Function endpoint
     * @param user - User object
     */
    constructor(
        private readonly authAzFunctionUrl: string,
        azFunctionUrl: string,
        user?: Pick<AzureMember, "userId" | "userName" | "additionalDetails">,
    ) {
        super(azFunctionUrl, user);
    }

    // In this context, a document is another name for container, so you can think of this function
    // as if it were named containerPostCreateCallback.
    public async documentPostCreateCallback?(documentId: string, creationToken: string): Promise<void> {
        await axios.post(this.authAzFunctionUrl, {
            params: {
                documentId,
                token: creationToken,
            },
        });
    }
}

Baca juga