Integrieren Sie Ihr Container-Produkt mit dem AWS Marketplace Metering Service mithilfe der AWS SDK for Java - AWS Marketplace

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Integrieren Sie Ihr Container-Produkt mit dem AWS Marketplace Metering Service mithilfe der AWS SDK for Java

Sie können den verwenden AWS SDK for Java , um ihn in den AWS Marketplace Metering Service zu integrieren. Die kontinuierliche Messung für den Einsatz von Software erfolgt automatisch durch den AWS Marketplace Metering Control Plane. Ihre Software muss keine spezifischen Aktionen zur Erfassung der Softwarenutzung ausführen, es sei denn, Sie rufen RegisterUsage einmal auf, damit die Messung der Softwarenutzung beginnt. Dieses Thema enthält eine Beispielimplementierung, bei der das AWS SDK for Java zur Integration in die RegisterUsage Aktion des AWS Marketplace Messdienstes verwendet wird.

RegisterUsagemuss sofort beim Starten eines Containers aufgerufen werden. Wenn Sie den Container nicht in den ersten 6 Stunden nach dem Start des Containers registrieren, bietet AWS Marketplace Metering Service keine Messgarantien für frühere Monate. Die Messung wird jedoch für den laufenden Monat fortgesetzt, bis der Container endet.

Den vollständigen Quellcode finden Sie unter RegisterUsage Java-Beispiel. Viele dieser Schritte gelten unabhängig von der AWS SDK Sprache.

Beispielschritte für die Integration von AWS Marketplace Metering Service
  1. Melden Sie sich beim AWS Marketplace Management Portal an.

  2. Wählen Sie unter Assets (Objekte) die Option Container, um mit der Erstellung eines neuen Container-Produkts zu beginnen. Das Erstellen des Produkts generiert den Produkt-Code für das Produkt, das mit Ihrem Container-Abbild integriert werden soll. Informationen zum Einstellen von IAM Berechtigungen finden Sie unterAWS Marketplace Mess- und Berechtigungs-API-Berechtigungen.

  3. Laden Sie das öffentliche AWSJava herunterSDK.

    Wichtig

    Um das Metering APIs von Amazon aus aufzurufenEKS, müssen Sie einen unterstützten AWS SDK und auf einem EKS Amazon-Cluster mit Kubernetes 1.13 oder höher ausführen.

  4. (Optional) Wenn Sie die RegisterUsage Aktion integrieren und eine Überprüfung der digitalen Signatur durchführen möchten, müssen Sie die Bibliothek zur BouncyCastleSignaturverifizierung im Klassenpfad Ihrer Anwendung konfigurieren.

    Wenn Sie JSON Web Token (JWT) verwenden möchten, müssen Sie auch JWTJava-Bibliotheken in den Klassenpfad Ihrer Anwendung aufnehmen. JWTDie Verwendung bietet einen einfacheren Ansatz zur Signaturüberprüfung, ist jedoch nicht erforderlich. Sie können stattdessen die eigenständige Version verwenden. BouncyCastle Unabhängig davon, ob Sie JWT oder verwenden BouncyCastle, müssen Sie ein Build-System wie Maven verwenden, um transitive Abhängigkeiten von BouncyCastle oder JWT in den Klassenpfad Ihrer Anwendung aufzunehmen.

    // Required for signature verification using code sample <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.60</version> </dependency> // This one is only required for JWT <dependency> <groupId>com.nimbusds</groupId> <artifactId>nimbus-jose-jwt</artifactId> <version>6.0</version> </dependency>
  5. Rufen Sie RegisterUsage von jedem kostenpflichtigen Container-Abbild in Ihrem Produktangebot auf. ProductCode und PublicKeyVersion sind erforderliche Parameter, alle anderen Eingaben sind optional. Es folgt ein Beispiel einer Nutzlast für RegisterUsage.

    { "ProductCode" : "string", // (required) "PublicKeyVersion": 1, // (required) "Nonce": "string", // (optional) to scope down the registration // to a specific running software // instance and guard against // replay attacks }
    Anmerkung

    Bei der Verbindung mit dem AWS Marketplace Metering Service können vorübergehende Probleme auftreten. AWS Marketplace empfiehlt dringend, Wiederholungsversuche für bis zu 30 Minuten mit exponentiellem Back-up durchzuführen, um kurzfristige Ausfälle oder Netzwerkprobleme zu vermeiden.

  6. RegisterUsagegeneriert mithilfe von SHA -256 eine RSA PSS digitale Signatur, mit der Sie die Authentizität der Anfrage überprüfen können. Die Signatur enthält die folgenden Felder: ProductCode, PublicKeyVersion und Nonce. Um die digitale Signatur zu überprüfen, müssen Sie diese Felder aus der Anforderung beibehalten. Der folgende Code ist ein Beispiel für eine Antwort auf einen RegisterUsage-Aufruf.

    { "Signature": "<<JWT Token>>" } // Where the JWT Token is composed of 3 dot-separated, // base-64 URL Encoded sections. // e.g. eyJhbGcVCJ9.eyJzdWIMzkwMjJ9.rrO9Qw0SXRWTe // Section 1: Header/Algorithm { "alg": "PS256", "typ": "JWT" } // Section 2: Payload { "ProductCode" : "string", "PublicKeyVersion": 1, "Nonce": "string", "iat": date // JWT issued at claim } // Section 3: RSA-PSS SHA256 signature "rrO9Q4FEi3gweH3X4lrt2okf5zwIatUUwERlw016wTy_21Nv8S..."
  7. Erstellen Sie eine neue Version Ihres Container-Images, die den RegisterUsage Call enthält, taggen Sie den Container und übertragen Sie ihn in eine beliebige Container-Registry, die mit Amazon ECS oder Amazon kompatibel istEKS, wie Amazon ECR oder Amazon ECR Public. Wenn Sie Amazon verwenden, stellen Sie sicherECR, dass das Konto, das die ECS Amazon-Aufgabe oder den EKS Amazon-Pod startet, über Berechtigungen für das ECR Amazon-Repository verfügt. Andernfalls schlägt der Start fehl.

  8. Erstellen Sie eine IAMRolle, die Ihrem Container die Berechtigung zum Aufrufen erteiltRegisterUsage, wie im folgenden Code definiert. Sie müssen diese IAM Rolle im Parameter Task Role der ECS Amazon-Aufgaben- oder EKS Amazon-Pod-Definition angeben.

    { "Version": "2012-10-17", "Statement": [ { "Action": [ "aws-marketplace:RegisterUsage" ], "Effect": "Allow", "Resource": "*" } ] }
  9. Erstellen Sie eine ECS Amazon-Aufgabe oder EKS Amazon-Pod-Definition, die auf den Container verweist, der in Schritt 7 integriert wurde, AWS Marketplace und auf die IAM Rolle verweist, die Sie in Schritt 7 erstellt haben. Sie sollten die AWS CloudTrail Protokollierung in der Aufgabendefinition aktivieren, wenn Sie die Protokollierung sehen möchten.

  10. Erstellen Sie einen Amazon ECS - oder EKS Amazon-Cluster, um Ihre Aufgabe oder Ihren Pod auszuführen. Weitere Informationen zum Erstellen eines ECS Amazon-Clusters finden Sie unter Creating a Cluster im Amazon Elastic Container Service Developer Guide. Weitere Informationen zum Erstellen eines EKS Amazon-Clusters (mit Kubernetes-Version 1.1.3.x oder höher) finden Sie unter Amazon-Cluster erstellen. EKS

  11. Konfigurieren Sie den Amazon ECS - oder EKS Amazon-Cluster und starten Sie die ECS Amazon-Aufgabendefinition oder den EKS Amazon-Pod, den Sie erstellt haben, in us-east-1 AWS-Region. Sie müssen diese Region nur während dieses Testprozesses, bevor das Produkt live geht, verwenden.

  12. Wenn Sie eine gültige Antwort von RegisterUsage erhalten, können Sie mit der Erstellung Ihres Containerprodukts beginnen. Bei Fragen wenden Sie sich bitte an das AWS Marketplace Seller Operations-Team.

RegisterUsage Java-Beispiel

Im folgenden Beispiel wird der AWS SDK for Java und AWS Marketplace Metering Service verwendet, um den RegisterUsage Vorgang aufzurufen. Die Signaturverifizierung ist optional. Wenn Sie die Signaturverifizierung aber durchführen möchten, müssen Sie die erforderlichen Bibliotheken für die Verifizierung von digitalen Signaturen einschließen. Dieses Beispiel dient lediglich der Veranschaulichung.

import com.amazonaws.auth.PEM; import com.amazonaws.services.marketplacemetering.AWSMarketplaceMetering; import com.amazonaws.services.marketplacemetering.AWSMarketplaceMeteringClientBuilder; import com.amazonaws.services.marketplacemetering.model.RegisterUsageRequest; import com.amazonaws.services.marketplacemetering.model.RegisterUsageResult; import com.amazonaws.util.json.Jackson; import com.fasterxml.jackson.databind.JsonNode; import com.nimbusds.jose.JWSObject; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.RSASSAVerifier; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.interfaces.RSAPublicKey; import java.util.Base64; import java.util.Optional; import java.util.UUID; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * Class for making calls out to AWS Marketplace Metering Service. */ class RegisterUsage { private static final String PRODUCT_CODE = "......."; private final AWSMarketplaceMetering registerUsageClient; private final SignatureVerifier signatureVerifier; private final int publicKeyVersion; public RegisterUsage(final SignatureVerifier signatureVerifier) { this.signatureVerifier = signatureVerifier; this.publicKeyVersion = PublicKeyProvider.PUBLIC_KEY_VERSION; this.registerUsageClient = AWSMarketplaceMeteringClientBuilder.standard().build(); } /** * Shows how to call RegisterUsage client and verify digital signature. */ public void callRegisterUsage() { RegisterUsageRequest request = new RegisterUsageRequest() .withProductCode(PRODUCT_CODE) .withPublicKeyVersion(publicKeyVersion) .withNonce(UUID.randomUUID().toString()); // Execute call to RegisterUsage (only need to call once at container startup) RegisterUsageResult result = this.registerUsageClient.registerUsage(request); // Verify Digital Signature w/o JWT boolean isSignatureValid = this.signatureVerifier.verify(request, result); if (!isSignatureValid) { throw new RuntimeException("Revoke entitlement, digital signature invalid."); } } } /** * Signature verification class with both a JWT-library based verification * and a non-library based implementation. */ class SignatureVerifier { private static BouncyCastleProvider BC = new BouncyCastleProvider(); private static final String SIGNATURE_ALGORITHM = "SHA256withRSA/PSS"; private final PublicKey publicKey; public SignatureVerifier(PublicKeyProvider publicKeyProvider) { this.publicKey = publicKeyProvider.getPublicKey().orElse(null); Security.addProvider(BC); } /** * Example signature verification using the NimbusJOSEJWT library to verify the JWT Token. * * @param request RegisterUsage Request. * @param result RegisterUsage Result. * @return true if the token matches. */ public boolean verifyUsingNimbusJOSEJWT(final RegisterUsageRequest request, final RegisterUsageResult result) { if (!getPublicKey().isPresent()) { return false; } try { JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) getPublicKey().get()); JWSObject jwsObject = JWSObject.parse(result.getSignature()); return jwsObject.verify(verifier) && validatePayload(jwsObject.getPayload().toString(), request, result); } catch (Exception e) { // log error return false; } } /** * Example signature verification without any JWT library support. * * @param request RegisterUsage Request. * @param result RegisterUsage Result. * @return true if the token matches. */ public boolean verify(final RegisterUsageRequest request, final RegisterUsageResult result) { if (!getPublicKey().isPresent()) { return false; } try { String[] jwtParts = result.getSignature().split("\\."); String header = jwtParts[0]; String payload = jwtParts[1]; String payloadSignature = jwtParts[2]; Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, BC); signature.initVerify(getPublicKey().get()); signature.update(String.format("%s.%s", header, payload).getBytes(StandardCharsets.UTF_8)); boolean verified = signature.verify(Base64.getUrlDecoder() .decode(payloadSignature.getBytes(StandardCharsets.UTF_8))); String decodedPayload = new String(Base64.getUrlDecoder().decode(payload)); return verified && validatePayload(decodedPayload, request, result); } catch (Exception e) { // log error return false; } } /** * Validate each value in the returned payload matches values originally * supplied in the request to RegisterUsage. TimeToLiveInMillis and * PublicKeyExpirationTimestamp will have the values in the payload compared * to values in the signature */ private boolean validatePayload(final String payload, final RegisterUsageRequest request, final RegisterUsageResult result) { try { JsonNode payloadJson = Jackson.getObjectMapper().readTree(payload); boolean matches = payloadJson.get("productCode") .asText() .equals(request.getProductCode()); matches = matches && payloadJson.get("nonce") .asText() .equals(request.getNonce()); return matches = matches && payloadJson.get("publicKeyVersion") .asText() .equals(String.valueOf(request.getPublicKeyVersion())); } catch (Exception ex) { // log error return false; } } private Optional<PublicKey> getPublicKey() { return Optional.ofNullable(this.publicKey); } } /** * Public key provider taking advantage of the AWS PEM Utility. */ class PublicKeyProvider { // Replace with your public key. Ensure there are new-lines ("\n") in the // string after "-----BEGIN PUBLIC KEY-----\n" and before "\n-----END PUBLIC KEY-----". private static final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd\n" + "UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs\n" + "HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D\n" + "o2kQ+X5xK9cipRgEKwIDAQAB\n" + "-----END PUBLIC KEY-----"; public static final int PUBLIC_KEY_VERSION = 1; public Optional<PublicKey> getPublicKey() { try { return Optional.of(PEM.readPublicKey(new ByteArrayInputStream( PUBLIC_KEY.getBytes(StandardCharsets.UTF_8)))); } catch (Exception e) { // log error return Optional.empty(); } } }