Partager via


Sécuriser le serveur de suppression pour l’environnement de test PlayReady

Aperçu

Le serveur PlayReady Secure Delete fournit un point de terminaison de test pour la validation des fonctionnalités de suppression sécurisée dans les implémentations PlayReady. La suppression sécurisée garantit que le contenu protégé et les licences associées peuvent être supprimés de manière sécurisée des appareils clients lorsque cela est nécessaire, en conservant les exigences de protection et de conformité du contenu.

Point de terminaison de service

Le serveur de test Secure Delete est disponible sur :

https://playready.directtaps.net/pr/svc/securedelete.asmx

Protocole de suppression sécurisée

Vue d’ensemble du protocole

La suppression sécurisée permet aux fournisseurs de contenu de déclencher à distance la suppression sécurisée du contenu et des licences :

  1. Le fournisseur de contenu détermine que la suppression est requise
  2. Le serveur génère une commande de suppression sécurisée
  3. La commande est remise à l’appareil client
  4. Le client valide et exécute la suppression sécurisée
  5. Le client signale l’achèvement de la suppression sur le serveur

Flux de messages

Content Provider       Secure Delete Server        Client Device
       |                        |                        |
       |-- Delete Request ----->|                        |
       |<-- Delete Command -----|                        |
       |                        |-- Push Command ------>|
       |                        |<-- Execution Report ---|
       |<-- Completion Report --|                        |

Configuration du serveur

Stratégie de suppression sécurisée

Configurez les exigences de suppression sécurisée dans les licences :

{
  "licenseType": "persistent",
  "keyId": "key-id-guid",
  "secureDelete": {
    "enabled": true,
    "serverUrl": "https://playready.directtaps.net/pr/svc/securedelete.asmx",
    "triggerMechanism": "remote|policy|expiration",
    "deletionScope": "license|content|both",
    "customData": {
      "contentId": "content-identifier",
      "policyId": "deletion-policy-id"
    }
  }
}

Stratégies de suppression

Définissez différents scénarios de suppression :

{
  "deletionPolicies": [
    {
      "policyId": "immediate-delete",
      "trigger": "remote-command",
      "scope": "both",
      "verification": "required"
    },
    {
      "policyId": "expiration-delete",
      "trigger": "license-expiration",
      "scope": "license",
      "gracePeriod": "PT24H"
    },
    {
      "policyId": "compliance-delete",
      "trigger": "compliance-violation",
      "scope": "content",
      "enforcement": "immediate"
    }
  ]
}

Points de terminaison d’API

Demander une suppression sécurisée

Point de terminaison :POST /pr/svc/securedelete.asmx/RequestDelete

Format de la demande :

POST /pr/svc/securedelete.asmx/RequestDelete HTTP/1.1
Host: playready.directtaps.net
Content-Type: application/json

{
  "contentId": "content-identifier",
  "deviceId": "target-device-id",
  "deletionScope": "license|content|both",
  "reason": "expiration|violation|request",
  "immediateExecution": true
}

Format de réponse :

{
  "deleteCommandId": "command-identifier",
  "status": "queued|sent|acknowledged|completed",
  "timestamp": "2024-01-15T10:30:00Z",
  "estimatedCompletion": "2024-01-15T10:35:00Z"
}

État de suppression de requête

Point de terminaison :GET /pr/svc/securedelete.asmx/QueryStatus

Format de la demande :

GET /pr/svc/securedelete.asmx/QueryStatus?commandId=COMMAND_ID HTTP/1.1
Host: playready.directtaps.net

Format de réponse :

{
  "commandId": "command-identifier",
  "status": "pending|in-progress|completed|failed",
  "progress": {
    "itemsToDelete": 5,
    "itemsDeleted": 3,
    "percentComplete": 60
  },
  "completionTime": "2024-01-15T10:35:00Z",
  "errorDetails": null
}

Fin de la suppression du rapport

Point de terminaison :POST /pr/svc/securedelete.asmx/ReportCompletion

Format de la demande :

POST /pr/svc/securedelete.asmx/ReportCompletion HTTP/1.1
Host: playready.directtaps.net
Content-Type: application/octet-stream

[Secure Delete Completion Report - Binary Format]

Scénarios de test

Test de suppression sécurisée de base

Testez le flux de suppression sécurisée standard :

async function testBasicSecureDelete() {
    // 1. Request secure delete for content
    const deleteRequest = {
        contentId: 'test-content-123',
        deviceId: 'test-device-456',
        deletionScope: 'both',
        reason: 'expiration',
        immediateExecution: true
    };
    
    const response = await requestSecureDelete(deleteRequest);
    
    // 2. Monitor deletion progress
    let status;
    do {
        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second
        status = await queryDeleteStatus(response.deleteCommandId);
    } while (status.status === 'pending' || status.status === 'in-progress');
    
    return status.status === 'completed';
}

Test de suppression basé sur des stratégies

Testez différentes stratégies de suppression :

async function testPolicyBasedDeletion() {
    const policies = [
        {
            name: 'Immediate Delete',
            config: { trigger: 'remote-command', scope: 'both' }
        },
        {
            name: 'Expiration Delete',
            config: { trigger: 'license-expiration', scope: 'license' }
        },
        {
            name: 'Selective Delete',
            config: { trigger: 'compliance-violation', scope: 'content' }
        }
    ];
    
    const results = [];
    for (const policy of policies) {
        try {
            const result = await testDeletionPolicy(policy.config);
            results.push({ policy: policy.name, result: 'PASS' });
        } catch (error) {
            results.push({ policy: policy.name, result: 'FAIL', error: error.message });
        }
    }
    
    return results;
}

Test de suppression par lots

Testez la suppression de contenu multiple :

async function testBatchDeletion() {
    const contentItems = [
        'content-001',
        'content-002', 
        'content-003',
        'content-004',
        'content-005'
    ];
    
    // Request batch deletion
    const batchRequest = {
        contentIds: contentItems,
        deviceId: 'test-device-789',
        deletionScope: 'both',
        reason: 'batch-cleanup'
    };
    
    const response = await requestBatchDelete(batchRequest);
    
    // Monitor batch progress
    const finalStatus = await monitorBatchProgress(response.batchCommandId);
    
    return {
        totalItems: contentItems.length,
        successfulDeletions: finalStatus.progress.itemsDeleted,
        failedDeletions: finalStatus.progress.itemsToDelete - finalStatus.progress.itemsDeleted,
        completionTime: finalStatus.completionTime
    };
}

Intégration du client

Implémentation JavaScript

class SecureDeleteClient {
    constructor(serverUrl) {
        this.serverUrl = serverUrl;
    }
    
    async requestDelete(deleteRequest) {
        const response = await fetch(`${this.serverUrl}/RequestDelete`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(deleteRequest)
        });
        
        if (!response.ok) {
            throw new Error(`Delete request failed: ${response.status}`);
        }
        
        return await response.json();
    }
    
    async queryStatus(commandId) {
        const response = await fetch(`${this.serverUrl}/QueryStatus?commandId=${commandId}`);
        
        if (!response.ok) {
            throw new Error(`Status query failed: ${response.status}`);
        }
        
        return await response.json();
    }
    
    async reportCompletion(completionData) {
        const response = await fetch(`${this.serverUrl}/ReportCompletion`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/octet-stream'
            },
            body: completionData
        });
        
        return response.ok;
    }
}

// Usage
const secureDeleteClient = new SecureDeleteClient('https://playready.directtaps.net/pr/svc/securedelete.asmx');

Implémentation C#

public class SecureDeleteClient
{
    private readonly HttpClient httpClient;
    private readonly string serverUrl;
    
    public SecureDeleteClient(string serverUrl)
    {
        this.serverUrl = serverUrl;
        this.httpClient = new HttpClient();
    }
    
    public async Task<DeleteResponse> RequestDeleteAsync(DeleteRequest request)
    {
        var json = JsonConvert.SerializeObject(request);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var response = await httpClient.PostAsync($"{serverUrl}/RequestDelete", content);
        response.EnsureSuccessStatusCode();
        
        var responseJson = await response.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<DeleteResponse>(responseJson);
    }
    
    public async Task<DeleteStatus> QueryStatusAsync(string commandId)
    {
        var response = await httpClient.GetAsync($"{serverUrl}/QueryStatus?commandId={commandId}");
        response.EnsureSuccessStatusCode();
        
        var json = await response.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<DeleteStatus>(json);
    }
    
    public async Task<bool> ReportCompletionAsync(byte[] completionData)
    {
        var content = new ByteArrayContent(completionData);
        content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        
        var response = await httpClient.PostAsync($"{serverUrl}/ReportCompletion", content);
        return response.IsSuccessStatusCode;
    }
}

Étendues de suppression

suppression de License-Only

Supprimez uniquement la licence, en conservant le contenu :

{
  "deletionScope": "license",
  "preserveContent": true,
  "licenseCleanup": {
    "removeFromStore": true,
    "clearCacheReferences": true,
    "revokeBindings": true
  }
}

Suppression de contenu uniquement

Supprimez les fichiers de contenu tout en préservant la licence :

{
  "deletionScope": "content",
  "preserveLicense": true,
  "contentCleanup": {
    "removeFiles": true,
    "clearTemporaryFiles": true,
    "cleanupMetadata": true
  }
}

Suppression complète

Supprimez la licence et le contenu :

{
  "deletionScope": "both",
  "thoroughCleanup": true,
  "verification": {
    "confirmLicenseRemoval": true,
    "confirmContentRemoval": true,
    "verifyNoResidualData": true
  }
}

Considérations relatives à la sécurité

Authentification de commande

Les commandes de suppression sécurisée doivent être authentifiées :

{
  "commandAuthentication": {
    "signature": "cryptographic-signature",
    "certificateChain": ["cert1", "cert2"],
    "timestamp": "2024-01-15T10:30:00Z",
    "nonce": "random-value"
  }
}

Exigences de vérification

Vérifiez que la suppression sécurisée est correctement exécutée :

{
  "verificationRequirements": {
    "cryptographicProof": true,
    "overwriteVerification": true,
    "witnessReporting": true,
    "tamperDetection": true
  }
}

Fonctionnalités avancées

Suppression conditionnelle

Configurer des déclencheurs de suppression conditionnelle :

{
  "conditionalDeletion": {
    "conditions": [
      {
        "type": "time-based",
        "trigger": "2024-12-31T23:59:59Z"
      },
      {
        "type": "usage-based",
        "trigger": "max-plays-exceeded"
      },
      {
        "type": "location-based",
        "trigger": "geographic-restriction"
      }
    ],
    "logicalOperator": "OR"
  }
}

Fonctionnalité de restauration

Prise en charge de la restauration de suppression (le cas échéant) :

{
  "rollbackSupport": {
    "enabled": true,
    "retentionPeriod": "PT72H",
    "backupLocation": "secure-backup-store",
    "rollbackConditions": ["deletion-error", "false-positive"]
  }
}

Surveillance et rapports

Suppression d’Analytics

Effectuez le suivi des opérations de suppression sécurisée :

async function getDeletionAnalytics(period) {
    const response = await fetch(`${serverUrl}/Analytics?period=${period}`);
    return await response.json();
}

// Example response
{
  "period": "24h",
  "totalDeletions": 150,
  "successfulDeletions": 145,
  "failedDeletions": 5,
  "averageExecutionTime": "2.3s",
  "deletionReasons": {
    "expiration": 89,
    "violation": 12,
    "request": 49
  }
}

Rapports de conformité

Générez des rapports de conformité pour l’audit :

async function generateComplianceReport(startDate, endDate) {
    const params = new URLSearchParams({
        startDate: startDate.toISOString(),
        endDate: endDate.toISOString(),
        format: 'detailed'
    });
    
    const response = await fetch(`${serverUrl}/ComplianceReport?${params}`);
    return await response.blob(); // Returns PDF report
}

Meilleures pratiques

Instructions d’implémentation

  1. Vérification : Toujours vérifier l’achèvement de la suppression
  2. Journalisation : Gérer les journaux de suppression détaillés
  3. Sécurité : Utiliser une authentification forte pour supprimer des commandes
  4. Récupération : Implémenter des stratégies de sauvegarde appropriées
  5. Test : Scénarios de suppression de tests approfondis

Optimisation des performances

  1. Opérations par lots : suppressions liées au groupe
  2. Traitement asynchrone : utiliser la suppression asynchrone pour les opérations volumineuses
  3. Gestion des ressources : surveiller les ressources système lors de la suppression
  4. Planification : Planification des suppressions pendant les périodes de faible utilisation

Gestion des erreurs

Scénarios d’erreur courants

  • Échecs d’authentification : informations d’identification non valides ou expirées
  • Contenu introuvable : le contenu spécifié n’existe pas
  • Conflits de suppression : contenu en cours d’utilisation
  • Erreurs système : problèmes de stockage ou de réseau
  • Violations de stratégie : suppression non autorisée par la stratégie

Récupération d’erreur

async function handleDeletionError(commandId, error) {
    switch (error.type) {
        case 'AUTHENTICATION_FAILED':
            // Refresh credentials and retry
            await refreshAuthToken();
            return await retryDeletion(commandId);
            
        case 'CONTENT_IN_USE':
            // Wait and retry
            await waitForContentRelease();
            return await retryDeletion(commandId);
            
        case 'SYSTEM_ERROR':
            // Log error and schedule retry
            await logSystemError(error);
            return await scheduleDeletionRetry(commandId);
            
        default:
            throw new Error(`Unhandled deletion error: ${error.message}`);
    }
}

Support et résolution des problèmes

Pour les problèmes liés à la fonctionnalité de suppression sécurisée :

  1. Vérifier que la suppression sécurisée est activée dans la licence
  2. Vérifier l’étendue de suppression et la configuration de la stratégie
  3. Valider l’authentification de commande
  4. Surveiller la progression et l’état de suppression
  5. Passer en revue les journaux d’erreurs pour des problèmes spécifiques

Étapes de dépannage courantes :

  • Tester avec des scénarios de suppression simplifiés
  • Vérifier la connectivité réseau au serveur
  • Vérifier les autorisations d’appareil pour la suppression de contenu
  • Valider les signatures de chiffrement
  • Passer en revue les conflits de stratégie

Pour obtenir une prise en charge supplémentaire, reportez-vous à la documentation principale des serveurs de test PlayReady .