Procedure: Een gebruiker valideren die een container heeft gemaakt

Wanneer u een container maakt in Azure Fluid Relay, kan de JWT van de ITokenProvider voor de aanvraag voor het maken slechts eenmaal worden gebruikt. Nadat u een container hebt gemaakt, moet de client een nieuwe JWT genereren die de document-id bevat (wat echt de container-id is) die tijdens het maken van de service wordt geleverd. Als een toepassing een autorisatieservice heeft die containertoegangsbeheer beheert, moet deze weten wie een container met een bepaalde id heeft gemaakt om het genereren van een nieuwe JWT te autoriseren voor toegang tot die container.

Een autorisatieservice informeren wanneer een container wordt gemaakt

Een toepassing kan worden gebonden aan de levenscyclus van het maken van containers door een openbare documentPostCreateCallback()-methode in de bijbehorende TokenProvidermethode te implementeren. (De naam van deze functie kan verwarrend zijn. Het is echt een callback voor het maken van een container .) Deze callback wordt direct geactiveerd nadat de container is gemaakt, voordat een client de nieuwe JWT aanvraagt, moet deze lees-/schrijfmachtigingen verkrijgen voor de container die is gemaakt.

De documentPostCreateCallback() ontvangt twee parameters: 1) de id van de container die is gemaakt (ook wel de 'document-id' genoemd) en 2) een JWT die is ondertekend door de service zonder machtigingsbereiken. De autorisatieservice kan de opgegeven JWT verifiëren en de informatie in de JWT gebruiken om de juiste gebruikersmachtigingen te verlenen voor de zojuist gemaakte container.

Een eindpunt maken voor de callback voor het maken van een container

Dit voorbeeld hieronder is een Azure-functie die is gebaseerd op het voorbeeld in Procedure: Een TokenProvider schrijven met een Azure-functie.

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;

Implementeer de documentPostCreateCallback

In deze voorbeeld-implementatie hieronder wordt de AzureFunctionTokenProvider uitgebreid en wordt de axios-bibliotheek gebruikt om een HTTP-aanvraag naar de Azure-functie te maken die wordt gebruikt voor het genereren van tokens.

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

Zie ook