Share via


Nasıl yapılır: Azure İşlevi ile TokenProvider Yazma

Dekont

Bu önizleme sürümü hizmet düzeyi sözleşmesi olmadan sağlanır ve üretim iş yükleri için önerilmez. Bazı özellikler desteklenmiyor olabileceği gibi özellikleri sınırlandırılmış da olabilir.

Akıcı Çerçeve, TokenProviders, Azure Fluid Relay hizmetine istekte bulunmak için kullanılan belirteçleri @fluidframework/azure-client oluşturmak ve imzalamaktan sorumludur. Akıcı Çerçeve geliştirme amacıyla basit, güvenli olmayan bir TokenProvider sağlar ve insecureTokenProvider olarak adlandırılır. Her Akışkan hizmeti, belirli bir hizmetin kimlik doğrulaması ve güvenlik konuları temelinde özel bir TokenProvider uygulamalıdır.

Oluşturduğunuz her Azure Fluid Relay kaynağına bir kiracı kimliği ve kendi benzersiz kiracı gizli anahtarı atanır. Gizli anahtar, paylaşılan bir gizli dizidir. Uygulamanız/hizmetiniz bunu bilir ve Azure Fluid Relay hizmeti de bunu bilir. TokenProviders istekleri imzalamak için gizli anahtarı bilmelidir, ancak gizli anahtar istemci koduna eklenemez.

Belirteçleri imzalamak için Azure İşlevi uygulama

Güvenli belirteç sağlayıcısı oluşturmaya yönelik bir seçenek, HTTPS uç noktası oluşturmak ve belirteçleri almak için bu uç noktaya kimliği doğrulanmış HTTPS istekleri yapan bir TokenProvider uygulaması oluşturmaktır. Bu yol, kiracı gizli anahtarını Azure Key Vault gibi güvenli bir konumda depolamanızı sağlar.

Çözümün tamamının iki parçası vardır:

  1. İstekleri kabul eden ve Azure Fluid Relay belirteçlerini döndüren bir HTTPS uç noktası.
  2. Bir uç noktanın URL'sini kabul eden ve ardından belirteçleri almak için bu uç noktaya istekte bulunan bir ITokenProvider uygulaması.

Azure İşlevleri kullanarak TokenProvider'ınız için uç nokta oluşturma

Azure İşlevleri kullanmak, böyle bir HTTPS uç noktası oluşturmanın hızlı bir yoludur.

Bu örnekte, kiracı anahtarınızı geçirerek belirteci getiren kendi HTTPTrigger Azure İşlevinizi nasıl oluşturacağınız gösterilmektedir.

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { ScopeType } from "@fluidframework/azure-client";
import { generateToken } from "@fluidframework/azure-service-utils";

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

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    // tenantId, documentId, userId and userName are required parameters
    const tenantId = (req.query.tenantId || (req.body && req.body.tenantId)) as string;
    const documentId = (req.query.documentId || (req.body && req.body.documentId)) as string | undefined;
    const userId = (req.query.userId || (req.body && req.body.userId)) as string;
    const userName = (req.query.userName || (req.body && req.body.userName)) as string;
    const scopes = (req.query.scopes || (req.body && req.body.scopes)) as ScopeType[];

    if (!tenantId) {
        context.res = {
            status: 400,
            body: "No tenantId provided in query params",
        };
        return;
    }

    if (!key) {
        context.res = {
            status: 404,
            body: `No key found for the provided tenantId: ${tenantId}`,
        };
        return;
    }

    let user = { name: userName, id: userId };

    // Will generate the token and returned by an ITokenProvider implementation to use with the AzureClient.
    const token = generateToken(
        tenantId,
        documentId,
        key,
        scopes ?? [ScopeType.DocRead, ScopeType.DocWrite, ScopeType.SummaryWrite],
        user
    );

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

export default httpTrigger;

generateToken Pakette @fluidframework/azure-service-utils bulunan işlevi, kiracının gizli anahtarı kullanılarak imzalanan belirli bir kullanıcı için bir belirteç oluşturur. Bu yöntem, belirtecin gizli diziyi açığa çıkarmadan istemciye döndürülmüş olmasını sağlar. Bunun yerine belirteç, verilen belgeye kapsamlı erişim sağlamak için gizli dizi kullanılarak sunucu tarafında oluşturulur. Aşağıdaki örnek ITokenProvider, belirteçleri almak için bu Azure İşlevine HTTP isteklerinde bulunur.

Azure İşlevini dağıtma

Azure İşlevleri çeşitli yollarla dağıtılabilir. Daha fazla bilgi için Azure İşlevleri dağıtma hakkında daha fazla bilgi için Azure İşlevleri belgelerinin Dağıt bölümüne bakın.

TokenProvider'i uygulama

TokenProviders birçok yolla uygulanabilir, ancak iki ayrı API çağrısı uygulamalıdır: fetchOrdererToken ve fetchStorageToken. Bu API'ler sırasıyla Akıcı sipariş veren ve depolama hizmetleri için belirteçleri getirmekle sorumludur. Her iki işlev de belirteç değerini temsil eden nesneler döndürür TokenResponse . Akıcı Çerçeve çalışma zamanı, belirteçleri almak için gerektiğinde bu iki API'yi çağırır. Uygulama kodunuz Azure Fluid Relay hizmetiyle bağlantı kurmak için yalnızca bir hizmet uç noktası kullanırken, azure istemcisinin hizmetle birlikte bu uç noktayı sipariş eden ve depolama uç noktası çiftine çevirdiğini unutmayın. Bu iki uç nokta bu oturum için bu noktadan itibaren kullanılır. Bu nedenle belirteçleri getirmek için her biri için birer tane olmak üzere iki ayrı işlevi uygulamanız gerekir.

Kiracı gizli anahtarının güvenli tutulduğundan emin olmak için güvenli bir arka uç konumunda depolanır ve yalnızca Azure İşlevi'nden erişilebilir. Belirteçleri almak için veuserName/documentIduserID ve değerlerini sağlayarak tenantID dağıtılan Azure İşlevinize bir GET veya POST isteği göndermeniz gerekir. Azure İşlevi, belirteci uygun şekilde oluşturmak ve imzalamak için kiracı kimliği ile kiracı anahtarı gizli dizisi arasındaki eşlemeden sorumludur.

Aşağıdaki örnek uygulama, Azure İşlevinize bu istekleri göndermeyi işler. HTTP istekleri yapmak için axios kitaplığını kullanır. Sunucu kodundan HTTP isteğinde bulunmak için diğer kitaplıkları veya yaklaşımları kullanabilirsiniz. Bu özel uygulama sizin için paketten @fluidframework/azure-client dışarı aktarma olarak da sağlanır.

import { ITokenProvider, ITokenResponse } from "@fluidframework/routerlicious-driver";
import axios from "axios";
import { AzureMember } from "./interfaces";

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

    public async fetchOrdererToken(tenantId: string, documentId?: string): Promise<ITokenResponse> {
        return {
            jwt: await this.getToken(tenantId, documentId),
        };
    }

    public async fetchStorageToken(tenantId: string, documentId: string): Promise<ITokenResponse> {
        return {
            jwt: await this.getToken(tenantId, documentId),
        };
    }

    private async getToken(tenantId: string, documentId: string | undefined): Promise<string> {
        const response = await axios.get(this.azFunctionUrl, {
            params: {
                tenantId,
                documentId,
                userId: this.user?.userId,
                userName: this.user?.userName,
                additionalDetails: this.user?.additionalDetails,
            },
        });
        return response.data as string;
    }
}

Verimlilik ve hata işleme ekleme

AzureFunctionTokenProvider, kendi özel belirteç sağlayıcınızı uygularken başlangıç noktası olarak ele alınması gereken basit bir uygulamasıdırTokenProvider. Üretime hazır belirteç sağlayıcısının uygulanması için belirteç sağlayıcısının işlemesi gereken çeşitli hata senaryolarını göz önünde bulundurmanız gerekir. Örneğin uygulama, AzureFunctionTokenProvider belirteci istemci tarafında önbelleğe almadığından ağ bağlantısı kesme durumlarını işleyemiyor.

Kapsayıcının bağlantısı kesildiğinde, bağlantı yöneticisi kapsayıcıya yeniden bağlanmadan önce TokenProvider'dan yeni bir belirteç almayı dener. Ağ bağlantısı kesildiğinde, içinde yapılan fetchOrdererToken API alma isteği başarısız olur ve yeniden denenemeyen bir hata oluşturur. Bu da kapsayıcının atılmasını ve bir ağ bağlantısı yeniden kurulu olsa bile yeniden bağlanamamasına neden olur.

Bu bağlantı kesme sorununun olası bir çözümü, Window.local Depolama dosyasında geçerli belirteçleri önbelleğe almaktır. Belirteç önbelleğe alındığında, ağ bağlantısı kesildiğinde bir API alma isteği yapmak yerine kapsayıcı geçerli bir depolanmış belirteç alır. Yerel olarak depolanan belirtecin süresinin belirli bir süre sonra dolabileceğini ve yine de yeni geçerli bir belirteç almak için api isteğinde bulunmanız gerekeceğini unutmayın. Bu durumda, tek bir başarısız girişimden sonra kapsayıcının yok edilmesini önlemek için ek hata işleme ve yeniden deneme mantığı gerekir.

Bu iyileştirmeleri uygulamayı nasıl seçeceğiniz tamamen size ve uygulamanızın gereksinimlerine bağlı. Belirteç çözümünde localStorage , her getContainer çağrıda bir ağ isteğini kaldırdığınız için uygulamanızda performans iyileştirmeleri de göreceğinizi unutmayın.

Gibi localStorage bir şeyle belirteç önbelleğe alma, güvenlik açısından etkilenebilir ve uygulamanız için hangi çözümün uygun olduğuna karar verirken kendi takdirinize bağlıdır. Belirteç önbelleğe alma işlemi gerçekleştirip uygulamamanıza bakılmaksızın, tek bir başarısız çağrıdan sonra kapsayıcının atılmaması için içine hata işleme ve fetchStorageToken yeniden deneme mantığı fetchOrdererToken eklemeniz gerekir. Örneğin çağrısının getToken yeniden denenen ve yalnızca belirtilen sayıda yeniden denemeden sonra hata oluşturan bir catch blokla bir bloğun içinde try sarmalandığını düşünün.

Ayrıca bkz.