Vorgehensweise: Überprüfen eines Benutzers, der einen Container erstellt hat

Wenn Sie einen Container in Azure Fluid Relay erstellen, kann das vom ITokenProvider für die Erstellungsanforderung bereitgestellte JWT nur einmal verwendet werden. Nach dem Erstellen eines Containers muss der Client ein neues JWT generieren, das die Dokument-ID enthält (die tatsächlich die Container-ID ist), die vom Dienst zur Erstellungszeit bereitgestellt wird. Wenn eine Anwendung über einen Autorisierungsdienst verfügt, der die Containerzugriffskontrolle verwaltet, muss sie wissen, wer einen Container mit einer bestimmten ID erstellt hat, um die Generierung eines neuen JWT für den Zugriff auf diesen Container zu autorisieren.

Informieren eines Autorisierungsdiensts, wenn ein Container erstellt wird

Eine Anwendung kann den Lebenszyklus der Containererstellung verknüpfen, indem sie eine öffentliche documentPostCreateCallback()-Methode in seiner TokenProviderAnwendung implementieren. (Der Name dieser Funktion kann verwirrend sein. Es ist wirklich ein Rückruf für die Erstellung von Postcontainern.) Dieser Rückruf wird direkt nach dem Erstellen des Containers ausgelöst, bevor ein Client den neuen JWT anfordert, dass er Lese-/Schreibberechtigungen für den erstellten Container erhält.

Die documentPostCreateCallback() empfangen zwei Parameter: 1) die ID des Containers, der erstellt wurde (auch als "Dokument-ID" bezeichnet) und 2) ein vom Dienst signiertes JWT ohne Berechtigungsbereiche. Der Autorisierungsdienst kann das angegebene JWT überprüfen und die Informationen im JWT verwenden, um die richtigen Benutzerberechtigungen für den neu erstellten Container zu erteilen.

Erstellen eines Endpunkts für den Containererstellungsrückruf

Dieses folgende Beispiel ist eine Azure-Funktion, die auf dem Beispiel in Vorgehensweise: Schreiben eines TokenProvider-Elements mit einer Azure-Funktion basiert.

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;

Implementieren des documentPostCreateCallback

Die folgende Beispielimplementierung erweitert den AzureFunctionTokenProvider und verwendet die axios-Bibliothek , um eine HTTP-Anforderung an die Azure-Funktion zu stellen, die zum Generieren von Token verwendet wird.

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

Siehe auch