Créer un jeton SAP de délégation d’utilisateur avec Stockage Blob Azure et JavaScript
Cet article explique comment créer un jeton SAS de délégation d’utilisateur pour utiliser la bibliothèque de client du Stockage Blob Azure v12 pour JavaScript. Une SAP de délégation d’utilisateur, introduite avec la version 2018-11-09, est sécurisée avec les informations d’identification Microsoft Entra et est prise en charge uniquement pour le service Blob :
- Accordez l’accès à un conteneur existant.
- Accordez l’accès à la création, à l’utilisation et à la suppression d’objets blob.
Pour créer une SAP de délégation d’utilisateur, un client doit disposer d’autorisations pour appeler l’opération blobServiceClient.getUserDelegationKey . La clé renvoyée par cette opération est utilisée pour signer la SAP de délégation d’utilisateur. Le principal de sécurité qui appelle cette opération doit se voir attribuer un rôle RBAC qui inclut l’action Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/.
Les autorisations accordées à un client qui possède la SAP sont l’intersection des autorisations qui ont été accordées au principal de sécurité qui a demandé la clé de délégation d’utilisateur et des autorisations accordées à la ressource sur le jeton SAP dans le champ autorisations signées (sp). Si une autorisation accordée au principal de sécurité via RBAC n’est pas également accordée sur le jeton SAP, cette autorisation n’est pas accordée au client qui tente d’utiliser la SAP pour accéder à la ressource.
Des exemples d’extraits de code sont disponibles dans GitHub en tant que fichiers Node.js exécutables.
Package (npm) | Exemples | Référence API | Code source de la bibliothèque | Envoyer des commentaires
Meilleures pratiques pour les jetons SAP de délégation d’utilisateur
Étant donné que toute personne disposant du jeton SAP peut l’utiliser pour accéder au conteneur et aux objets blob, vous devez configurer le jeton SAP avec les autorisations les plus restrictives qui permettent néanmoins au jeton d’effectuer les tâches nécessaires.
Bonnes pratiques pour les jetons SAP
Utiliser DefaultAzureCredential dans le cloud Azure
Pour vous authentifier auprès d’Azure sans secrets, configurez une identité managée. Cette approche permet à votre code d’utiliser DefaultAzureCredential.
Pour configurer une identité managée pour le cloud Azure :
- Créer une identité managée
- Définir les rôles de stockage appropriés pour l’identité
- Configurer votre environnement Azure pour qu’il fonctionne avec votre identité managée
Lorsque ces deux tâches sont terminées, utilisez DefaultAzureCredential au lieu d’une chaîne de connexion ou d’une clé de compte. Cette approche permet à tous vos environnements d’utiliser exactement le même code source sans le problème d’utilisation des secrets dans le code source.
Utiliser DefaultAzureCredential dans le développement local
Dans votre environnement de développement local, votre identité Azure (votre compte personnel ou de développement que vous utilisez pour vous connecter au Portail Azure) doit s’authentifier auprès d’Azure pour utiliser le même code dans les runtimes locaux et cloud.
Conteneur : ajouter les dépendances nécessaires à votre application
Incluez les dépendances nécessaires pour créer un jeton SAP de conteneur.
const {
DefaultAzureCredential
} = require('@azure/identity');
const {
ContainerClient,
BlobServiceClient,
ContainerSASPermissions,
generateBlobSASQueryParameters,
SASProtocol
} = require('@azure/storage-blob');
// used for local environment variables
require('dotenv').config();
Conteneur : obtenir des variables d’environnement
Le nom du compte de stockage Blob et le nom du conteneur sont les valeurs minimales requises pour créer un jeton SAP de conteneur :
// Get environment variables for DefaultAzureCredential
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
Créer une SAP avec DefaultAzureCredential
Les étapes conceptuelles suivantes sont requises pour créer un jeton SAP avec DefaultAzureCredential :
- Configurer DefaultAzureCredential
- Développement local : utiliser des identités personnelles et définir des rôles pour le stockage
- Cloud Azure - Créer une identité managée
- Utiliser DefaultAzureCredential pour obtenir la clé de délégation utilisateur avec UserDelegationKey
- Utilisez la clé de délégation utilisateur pour construire le jeton SAP avec les champs appropriés avec generateBlobSASQueryParameters
Conteneur : créer un jeton SAP avec DefaultAzureCredential
Avec l’identité configurée, utilisez le code suivant pour créer un jeton SAP de délégation d’utilisateur pour un compte et un conteneur existants :
// Server creates User Delegation SAS Token for container
async function createContainerSas() {
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Best practice: create time limits
const TEN_MINUTES = 10 * 60 * 1000;
const NOW = new Date();
// Best practice: set start time a little before current time to
// make sure any clock issues are avoided
const TEN_MINUTES_BEFORE_NOW = new Date(NOW.valueOf() - TEN_MINUTES);
const TEN_MINUTES_AFTER_NOW = new Date(NOW.valueOf() + TEN_MINUTES);
// Best practice: use managed identity - DefaultAzureCredential
const blobServiceClient = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net`,
new DefaultAzureCredential()
);
// Best practice: delegation key is time-limited
// When using a user delegation key, container must already exist
const userDelegationKey = await blobServiceClient.getUserDelegationKey(
TEN_MINUTES_BEFORE_NOW,
TEN_MINUTES_AFTER_NOW
);
// Need only list permission to list blobs
const containerPermissionsForAnonymousUser = "l";
// Best practice: SAS options are time-limited
const sasOptions = {
containerName,
permissions: ContainerSASPermissions.parse(containerPermissionsForAnonymousUser),
protocol: SASProtocol.HttpsAndHttp,
startsOn: TEN_MINUTES_BEFORE_NOW,
expiresOn: TEN_MINUTES_AFTER_NOW
};
const sasToken = generateBlobSASQueryParameters(
sasOptions,
userDelegationKey,
accountName
).toString();
return sasToken;
}
Le code serveur précédent crée un flux de valeurs pour créer le jeton SAP de conteneur :
- Créez le BlobServiceClient avec DefaultAzureCredential
- Utilisez l’opération blobServiceClient.getUserDelegationKey pour créer une UserDelegationKey
- Utilisez la clé pour créer la chaîne de jeton SAP avec generateBlobSASQueryParameters
Une fois que vous avez créé le jeton SAP de conteneur, vous pouvez le fournir au client, qui consommera le jeton. Le client peut ensuite l’utiliser pour répertorier les objets blob dans un conteneur. Un exemple de code client montre comment tester la SAP en tant que consommateur.
Conteneur : utiliser un jeton SAP
Une fois le jeton SAP de conteneur créé, utilisez-le. En guise d’exemple d’utilisation du jeton SAP, vous :
- Construisez une URL complète, comprenant le nom du conteneur et la chaîne de requête. La chaîne de requête est le jeton SAP.
- Créez un ContainerClient avec l’URL du conteneur.
- Utilisez le client : dans cet exemple, répertoriez les objets blob dans le conteneur avec listBlobsFlat.
// Client or another process uses SAS token to use container
async function listBlobs(sasToken){
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Create Url
// SAS token is the query string with typical `?` delimiter
const sasUrl = `https://${accountName}.blob.core.windows.net/${containerName}?${sasToken}`;
console.log(`\nContainerUrl = ${sasUrl}\n`);
// Create container client from SAS token url
const containerClient = new ContainerClient(sasUrl);
let i = 1;
// List blobs in container
for await (const blob of containerClient.listBlobsFlat()) {
console.log(`Blob ${i++}: ${blob.name}`);
}
}
Blob : ajouter les dépendances nécessaires à votre application
Incluez les dépendances nécessaires pour créer un jeton SAP d’objet blob.
const {
DefaultAzureCredential
} = require('@azure/identity');
const {
BlockBlobClient,
BlobServiceClient,
BlobSASPermissions,
generateBlobSASQueryParameters,
SASProtocol
} = require('@azure/storage-blob');
// used for local environment variables
require('dotenv').config();
Blob : définir les variables d’environnement
Le nom du compte de stockage Blob et le nom du conteneur sont les valeurs minimales requises pour créer un jeton SAP d’objet blob :
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
Lorsque vous devez créer un jeton SAP d’objet blob, vous devez avoir le nom de l’objet blob pour créer le jeton SAP. Cela sera prédéterminé comme un nom d’objet blob aléatoire, un nom d’objet blob soumis par l’utilisateur ou un nom généré à partir de votre application.
// Create random blob name for text file
const blobName = `${(0|Math.random()*9e6).toString(36)}.txt`;
Objet blob : créer un jeton SAP avec DefaultAzureCredential
Avec l’identité configurée, utilisez le code suivant pour créer un jeton SAP de délégation d’utilisateur pour un compte et un conteneur existants :
// Server creates User Delegation SAS Token for blob
async function createBlobSas(blobName) {
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Best practice: create time limits
const TEN_MINUTES = 10 * 60 * 1000;
const NOW = new Date();
// Best practice: set start time a little before current time to
// make sure any clock issues are avoided
const TEN_MINUTES_BEFORE_NOW = new Date(NOW.valueOf() - TEN_MINUTES);
const TEN_MINUTES_AFTER_NOW = new Date(NOW.valueOf() + TEN_MINUTES);
// Best practice: use managed identity - DefaultAzureCredential
const blobServiceClient = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net`,
new DefaultAzureCredential()
);
// Best practice: delegation key is time-limited
// When using a user delegation key, container must already exist
const userDelegationKey = await blobServiceClient.getUserDelegationKey(
TEN_MINUTES_BEFORE_NOW,
TEN_MINUTES_AFTER_NOW
);
// Need only create/write permission to upload file
const blobPermissionsForAnonymousUser = "cw"
// Best practice: SAS options are time-limited
const sasOptions = {
blobName,
containerName,
permissions: BlobSASPermissions.parse(blobPermissionsForAnonymousUser),
protocol: SASProtocol.HttpsAndHttp,
startsOn: TEN_MINUTES_BEFORE_NOW,
expiresOn: TEN_MINUTES_AFTER_NOW
};
const sasToken = generateBlobSASQueryParameters(
sasOptions,
userDelegationKey,
accountName
).toString();
return sasToken;
}
Le code précédent crée un flux de valeurs pour créer le jeton SAP de conteneur :
- Créez le BlobServiceClient avec DefaultAzureCredential
- Utilisez l’opération blobServiceClient.getUserDelegationKey pour créer une UserDelegationKey
- Utilisez la clé pour créer la chaîne de jeton SAP. Si le nom de l’objet blob n’a pas été spécifié dans les options, le jeton SAP est un jeton de conteneur.
Une fois que vous avez créé le jeton SAP d’objet blob, vous pouvez le fournir au client, qui consommera le jeton. Le client peut ensuite l’utiliser pour charger un objet blob. Un exemple de code client montre comment tester la SAP en tant que consommateur.
Blob : utiliser le jeton SAP
Une fois le jeton SAP d’objet blob créé, utilisez-le. En guise d’exemple d’utilisation du jeton SAP, vous :
- Construisez une URL complète, comprenant le nom du conteneur, le nom d’objet blob et la chaîne de requête. La chaîne de requête est le jeton SAP.
- Créez un BlockBlobClient avec l’URL du conteneur.
- Utilisez le client : dans cet exemple, chargez un objet blob avec upload.
// Client or another process uses SAS token to upload content to blob
async function uploadStringToBlob(blobName, sasToken, textAsString){
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Create Url SAS token as query string with typical `?` delimiter
const sasUrl = `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}?${sasToken}`;
console.log(`\nBlobUrl = ${sasUrl}\n`);
// Create blob client from SAS token url
const blockBlobClient = new BlockBlobClient(sasUrl);
// Upload string
await blockBlobClient.upload(textAsString, textAsString.length, undefined);
}