Freigeben über


Szenario: Signierte HTTP-Anforderungen (SHR)

Verwenden Sie signierte HTTP-Anforderungen (SHR) mit dem Microsoft Entra SDK für AgentID, um die PoP-Tokensicherheit (Proof-of-Possession) zu implementieren. PoP-Token binden Token kryptografisch an einen öffentlichen Schlüssel, verhindern Tokendiebstahl- und Replay-Angriffe beim Aufrufen von downstream-APIs.

Voraussetzungen

  • Ein Azure-Konto mit einem aktiven Abonnement. Kostenlos ein Konto erstellen.
  • Microsoft Entra SDK für AgentID bereitgestellt und ausgeführt mit aktivierter Unterstützung für Besitznachweise. Anweisungen zur Einrichtung finden Sie im Installationshandbuch .
  • RSA-Schlüsselpaar – Generieren Sie ein öffentliches/privates Schlüsselpaar für die kryptografische Signatur. Der öffentliche Schlüssel wird im SDK konfiguriert, während der private Schlüssel in Ihrer Anwendung sicher bleibt.
  • Nachgeschaltete API, die PoP-Token unterstützt – die Ziel-API muss die Überprüfung von Token für den Besitznachweis und die Überprüfung von Signaturen mithilfe des öffentlichen Schlüssels vornehmen.
  • Entsprechende Berechtigungen in der Microsoft Entra-ID – Ihr Konto muss über Berechtigungen zum Registrieren von Anwendungen verfügen und PoP-Einstellungen konfigurieren.

Schlüsselpaar generieren

Generieren Sie vor der Implementierung von PoP-Token ein RSA-Schlüsselpaar. Der private Schlüssel verbleibt in Ihrer Anwendung zum Signieren von Anforderungen, während der öffentliche Schlüssel im Microsoft Entra SDK für AgentID konfiguriert ist:

# Generate RSA private key
openssl genrsa -out private.pem 2048

# Extract public key
openssl rsa -in private.pem -pubout -out public.pem

# Base64 encode public key for configuration
base64 -w 0 public.pem > public.pem.b64

# View base64-encoded key
cat public.pem.b64

Konfiguration

Konfigurieren Sie das Microsoft Entra SDK für AgentID mit Ihren öffentlichen RSA-Schlüssel- und downstream-API-Einstellungen. Speichern vertraulicher Schlüssel in sicheren Konfigurationsspeichern:

SDK-Konfiguration

apiVersion: v1
kind: Secret
metadata:
  name: shr-keys
type: Opaque
data:
  public-key: <base64-encoded-public-key>

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: sidecar-config
data:
  # ... other configuration ...
  DownstreamApis__SecureApi__BaseUrl: "https://api.contoso.com"
  DownstreamApis__SecureApi__Scopes: "api://secureapi/.default"
  DownstreamApis__SecureApi__AcquireTokenOptions__PopPublicKey: "<base64-public-key>"

Verwendungsbeispiele

Um PoP-Token in Ihrer Anwendung zu verwenden, fordern Sie ein PoP-Token aus dem Microsoft Entra SDK für AgentID an, indem Sie Ihren öffentlichen Schlüssel angeben, und fügen Sie es dann in API-Anforderungen ein:

TypeScript

// Request PoP token
async function getPopToken(incomingToken: string, publicKey: string): Promise<string> {
  const sidecarUrl = process.env.SIDECAR_URL!;
  
  const response = await fetch(
    `${sidecarUrl}/AuthorizationHeader/SecureApi?` +
    `optionsOverride.AcquireTokenOptions.PopPublicKey=${encodeURIComponent(publicKey)}`,
    {
      headers: {
        'Authorization': incomingToken
      }
    }
  );
  
  const data = await response.json();
  return data.authorizationHeader; // Returns "PoP <pop-token>"
}

// Use PoP token with signed request
async function callSecureApi(incomingToken: string, publicKey: string, privateKey: string) {
  // Get PoP token from the SDK
  const popToken = await getPopToken(incomingToken, publicKey);
  
  // Make request to API with PoP token
  const response = await fetch('https://api.contoso.com/secure/data', {
    headers: {
      'Authorization': popToken
    }
  });
  
  return await response.json();
}

Python

import base64
import requests
import os

def get_pop_token(incoming_token: str, public_key: str) -> str:
    """Get a PoP token from the SDK."""
    sidecar_url = os.getenv('SIDECAR_URL', 'http://localhost:5000')
    
    response = requests.get(
        f"{sidecar_url}/AuthorizationHeader/SecureApi",
        params={
            'optionsOverride.AcquireTokenOptions.PopPublicKey': public_key
        },
        headers={'Authorization': incoming_token}
    )
    
    response.raise_for_status()
    data = response.json()
    return data['authorizationHeader']

def call_secure_api(incoming_token: str, public_key_b64: str):
    """Call API with PoP token."""
    pop_token = get_pop_token(incoming_token, public_key_b64)
    
    response = requests.get(
        'https://api.contoso.com/secure/data',
        headers={'Authorization': pop_token}
    )
    
    return response.json()

SHR pro Anforderung

Sie können PoP-Einstellungen pro Anforderung überschreiben, indem Sie verschiedene öffentliche Schlüssel für verschiedene APIs oder Bereiche angeben:

// Enable SHR for specific request
const response = await fetch(
  `${sidecarUrl}/AuthorizationHeader/Graph?` +
  `optionsOverride.AcquireTokenOptions.PopPublicKey=${encodeURIComponent(publicKey)}`,
  {
    headers: { 'Authorization': incomingToken }
  }
);

Schlüsselverwaltung

Implementieren Sie sichere Schlüsselverwaltungsmethoden, um Ihre RSA-Schlüssel zu schützen und die Schlüsseldrehung bei Bedarf zu aktivieren:

Sicherer Schlüsselspeicher

Sicheres Speichern von RSA-Schlüsseln mithilfe von Kubernetes Secrets:

# Store keys in Kubernetes Secret
apiVersion: v1
kind: Secret
metadata:
  name: shr-keys
type: Opaque
data:
  public-key: <base64-encoded-public-key>
  private-key: <base64-encoded-private-key>

---
# Mount keys in application
volumes:
- name: shr-keys
  secret:
    secretName: shr-keys
    defaultMode: 0400

containers:
- name: app
  volumeMounts:
  - name: shr-keys
    mountPath: /keys
    readOnly: true

Schlüsselrotation

Regelmäßiges Drehen von Signaturschlüsseln mithilfe von OpenSSL- und Updatekonfigurationen:

#!/bin/bash
# Script to rotate SHR keys

# Generate new key pair
openssl genrsa -out private-new.pem 2048
openssl rsa -in private-new.pem -pubout -out public-new.pem
base64 -w 0 public-new.pem > public-new.pem.b64

# Update Kubernetes secret
kubectl create secret generic shr-keys-new \
  --from-file=public-key=public-new.pem.b64 \
  --from-file=private-key=private-new.pem \
  --dry-run=client -o yaml | kubectl apply -f -

# Update deployment to use new keys
kubectl rollout restart deployment myapp

Überprüfen von PoP-Token

Die downstream-API muss das PoP-Token überprüfen, um sicherzustellen, dass es ordnungsgemäß signiert und an die Anforderung gebunden ist:

  1. Überprüfen der JWT-Signatur mithilfe des öffentlichen Schlüssels, der aus dem Token extrahiert wurde
  2. Überprüfen standardmäßiger JWT-Ansprüche (Aussteller, Zielgruppe, Ablauf)
  3. Überprüfen, ob der cnf Anspruch den erwarteten öffentlichen Schlüssel enthält
  4. Überprüfen, ob die HTTP-Anforderungssignatur mit dem Schlüssel aus dem cnf Anspruch übereinstimmt

Vorteile

Die Implementierung von signierten HTTP-Anforderungen mit Token für den Nachweis des Besitzes bietet mehrere Sicherheitsvorteile:

  • Tokenbindung: Jedes Token ist kryptografisch an einen bestimmten öffentlichen Schlüssel gebunden und verhindert die nicht autorisierte Verwendung, auch wenn sie abgefangen wurde.
  • Replay Prevention: Ein Angreifer kann kein erfasstes Token wiedergeben, ohne den entsprechenden privaten Schlüssel zu besitzen.
  • Erweiterte Sicherheit: Bietet Schutz vor Tokendiebstahl, insbesondere für vertrauliche Vorgänge und umgebungen mit hoher Sicherheit.
  • Besitznachweis: Beweist kryptografisch, dass der Client den privaten Schlüssel besitzt, der dem Token entspricht.

Bewährte Methoden

Befolgen Sie bei der Implementierung signierter HTTP-Anforderungen die folgenden Methoden, um die Sicherheit und Betriebssicherheit aufrechtzuerhalten:

  • Sichere private Schlüssel: Machen Sie niemals private Schlüssel in Protokollen, Konfigurationsdateien oder Coderepositorys verfügbar. Speichern Sie sie sicher mithilfe von Schlüsseltresorn oder Konfigurationsverwaltungssystemen.
  • Regelmäßiges Drehen von Schlüsseln: Implementieren Eines Schlüsseldrehungszeitplans, um die Auswirkungen potenzieller Schlüsselkompromittierungen zu minimieren. Aktualisieren Sie sowohl die SDK- als auch die Downstream-APIs während der Rotation.
  • Verwenden Sie Per-API Schlüssel: Verwenden Sie unterschiedliche Schlüsselpaare für verschiedene APIs oder Sicherheitszonen, um die Auswirkungen zu begrenzen, wenn ein Schlüssel kompromittiert wird.
  • Überwachung der Nutzung: Prüfung und Überwachung der PoP-Token-Nutzung, um verdächtige Muster zu erkennen oder unautorisierte Zugriffsversuche zu identifizieren.
  • Testen Sie gründlich: Überprüfen Sie, ob die PoP-Token-Überprüfung korrekt funktioniert, bevor Sie sie in die Produktion einführen, und stellen Sie sicher, dass die Signaturüberprüfung sowie die Anforderungsbindungsprüfungen bestehen.

Nächste Schritte

Nach der Implementierung von PoP-Token: