Share via


Gör så här: Verifiera en användare som har skapat en container

När du skapar en container i Azure Fluid Relay kan JWT som tillhandahålls av ITokenProvider för skapandebegäran endast användas en gång. När du har skapat en container måste klienten generera en ny JWT som innehåller dokument-ID:t (som verkligen är container-ID:t) som tillhandahålls av tjänsten vid skapandetillfället. Om ett program har en auktoriseringstjänst som hanterar åtkomstkontroll för containrar måste det veta vem som skapade en container med ett visst ID för att kunna auktorisera genereringen av en ny JWT för åtkomst till containern.

Informera en auktoriseringstjänst när en container skapas

Ett program kan kopplas till livscykeln för att skapa containrar genom att implementera en offentlig documentPostCreateCallback()-metod i dess TokenProvider. (Namnet på den här funktionen kan vara förvirrande. Det är verkligen ett återanrop för att skapa en container .) Återanropet utlöses direkt efter att containern har skapats innan en klient begär den nya JWT som den behöver för att få läs- och skrivbehörighet till containern som skapades.

Tar documentPostCreateCallback() emot två parametrar: 1) ID:t för containern som skapades (kallas även "dokument-ID") och 2) en JWT signerad av tjänsten utan behörighetsomfång. Auktoriseringstjänsten kan verifiera den angivna JWT och använda informationen i JWT för att bevilja rätt användarbehörigheter för den nyligen skapade containern.

Skapa en slutpunkt för återanrop för att skapa containrar

Det här exemplet nedan är en Azure-funktion som baseras på exemplet i How to: Write a TokenProvider with an Azure Function (Så här skriver du en TokenProvider med en Azure-funktion).

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;

Implementera documentPostCreateCallback

Den här exempelimplementeringen nedan utökar AzureFunctionTokenProvider och använder axios-biblioteket för att göra en HTTP-begäran till Den Azure-funktion som används för att generera 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,
            },
        });
    }
}

Se även