如何:驗證建立容器的使用者
當您在 Azure Fluid Relay 中建立容器時,ITokenProvider 為建立要求提供的 JWT 只能使用一次。 建立容器之後,用戶端必須產生新的 JWT,其中包含服務在建立時所提供的檔識別碼(這實際上是容器識別碼)。 如果應用程式具有管理容器存取控制的授權服務,它必須知道誰建立了具有指定識別碼的容器,才能授權產生新的 JWT 以存取該容器。
建立容器時通知授權服務
應用程式可以藉由在其 中 TokenProvider
實作公用 documentPostCreateCallback() 方法來系結至容器建立生命週期。 (此函式的名稱可能會造成混淆。這確實是建立容器 後 回呼。此回呼會在建立容器之後直接觸發,用戶端要求新的 JWT 之前,它必須取得所建立容器的讀取/寫入權限。
會收到 documentPostCreateCallback()
兩個參數:1) 建立的容器識別碼(也稱為「檔識別碼」)和 2)由服務簽署且沒有許可權範圍的 JWT。 授權服務可以驗證指定的 JWT,並使用 JWT 中的資訊,為新建立的容器授與正確的使用者權限。
建立容器建立回呼的端點
下列範例是以 如何:使用 Azure 函式撰寫 TokenProvider 中的 範例為基礎的 Azure 函 式 。
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;
實作 documentPostCreateCallback
下列範例實作會擴充 AzureFunctionTokenProvider,並使用 axios 程式庫對用來產生權杖的 Azure 函式提出 HTTP 要求。
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,
},
});
}
}