Integrazione del prodotto contenitore con il AWS Marketplace Metering Service utilizzando AWS SDK for Java - Marketplace AWS

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Integrazione del prodotto contenitore con il AWS Marketplace Metering Service utilizzando AWS SDK for Java

Puoi utilizzarlo AWS SDK for Java per l'integrazione con il AWS Marketplace Metering Service. La misurazione continua per l'uso del software viene gestita automaticamente dal Marketplace AWS Metering Control Plane. Non è necessario che il software esegua alcuna azione specifica di misurazione, ad eccezione di RegisterUsage una chiamata una volta per iniziare la misurazione dell'utilizzo del software. Questo argomento fornisce un esempio di implementazione che utilizza l'azione del servizio di misurazione AWS SDK for Java per integrarsi con il Marketplace AWS Metering Service. RegisterUsage

RegisterUsagedeve essere chiamato immediatamente al momento del lancio di un contenitore. Se non registri il container nelle prime 6 ore dal lancio del container, AWS Marketplace Metering Service non fornisce alcuna garanzia di misurazione per i mesi precedenti. Tuttavia, la misurazione continuerà per il mese in corso fino alla scadenza del container.

Per il codice sorgente completo, vediRegisterUsage Esempio di Java. Molti di questi passaggi si applicano indipendentemente dalla AWS SDK lingua.

Esempi di passaggi per l'integrazione AWS del Marketplace Metering Service
  1. Accedi alla Portale di gestione Marketplace AWS.

  2. Da Assets scegli Containers per iniziare a creare un nuovo prodotto container. La creazione del prodotto genera il codice prodotto per il prodotto da integrare con l'immagine del contenitore. Per informazioni sull'impostazione delle IAM autorizzazioni, consultaMarketplace AWS autorizzazioni API di misurazione e autorizzazione.

  3. Scaricate la versione pubblica di AWSJava SDK.

    Importante

    Per richiamare la misurazione APIs da AmazonEKS, devi utilizzare un cluster Amazon supportato AWS SDK ed eseguito su un EKS cluster Amazon che esegue Kubernetes 1.13 o versione successiva.

  4. (Facoltativo) Se ti stai integrando con l'RegisterUsageazione e desideri eseguire la verifica della firma digitale, devi configurare la libreria di verifica delle firme nel classpath dell'BouncyCastleapplicazione.

    Se desideri utilizzare JSON Web Token (JWT), devi includere anche le librerie JWTJava nel classpath dell'applicazione. L'utilizzo JWT fornisce un approccio più semplice alla verifica della firma, ma non è obbligatorio ed è possibile utilizzare invece la modalità standalone. BouncyCastle Indipendentemente dal fatto che si utilizzi JWT o BouncyCastle, è necessario utilizzare un sistema di compilazione come Maven per includere dipendenze transitive di o nel percorso di classe dell' BouncyCastle applicazione. JWT

    // 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. Chiama RegisterUsage da ogni immagine di container a pagamento presente nella tua offerta di prodotti. ProductCodee PublicKeyVersion sono parametri obbligatori e tutti gli altri input sono opzionali. Di seguito è riportato un esempio di payload per. 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 }
    Nota

    È possibile riscontrare problemi temporanei nella connessione al AWS Marketplace Metering Service. Marketplace AWS consiglia vivamente di implementare nuovi tentativi per un massimo di 30 minuti, con interruzione esponenziale, per evitare interruzioni a breve termine o problemi di rete.

  6. RegisterUsagegenera una firma PSS digitale RSA - utilizzando SHA -256 che è possibile utilizzare per verificare l'autenticità della richiesta. La firma include i seguenti campi: ProductCodePublicKeyVersion, e. Nonce Per verificare la firma digitale, è necessario conservare questi campi della richiesta. Il codice seguente è un esempio di risposta a una RegisterUsage chiamata.

    { "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. Ricostruisci una nuova versione dell'immagine del contenitore che includa la RegisterUsage chiamata, tagga il contenitore e inviala a qualsiasi registro di container compatibile con Amazon ECS o AmazonEKS, come Amazon ECR o Amazon ECR Public. Se utilizzi AmazonECR, assicurati che l'account che avvia l'ECSattività Amazon o il EKS pod Amazon disponga delle autorizzazioni per l'accesso al repository AmazonECR. In caso contrario, il lancio fallisce.

  8. Crea un IAMruolo che conceda l'autorizzazione alla chiamata del contenitoreRegisterUsage, come definito nel codice seguente. È necessario fornire questo IAM ruolo nel parametro Task Role della definizione Amazon ECS task o Amazon EKS pod.

    { "Version": "2012-10-17", "Statement": [ { "Action": [ "aws-marketplace:RegisterUsage" ], "Effect": "Allow", "Resource": "*" } ] }
  9. Crea un'ECSattività Amazon o una definizione di Amazon EKS pod che faccia riferimento al contenitore integrato Marketplace AWS e al IAM ruolo che hai creato nel passaggio 7. È necessario abilitare AWS CloudTrail la registrazione nella definizione dell'attività se si desidera visualizzare la registrazione.

  10. Crea un EKS cluster Amazon ECS o Amazon per eseguire la tua attività o il tuo pod. Per ulteriori informazioni sulla creazione di un ECS cluster Amazon, consulta Creating a Cluster nella Amazon Elastic Container Service Developer Guide. Per ulteriori informazioni sulla creazione di un EKS cluster Amazon (utilizzando Kubernetes versione 1.1.3.x o successiva), consulta Creazione di un cluster Amazon. EKS

  11. Configura il EKS cluster Amazon ECS o Amazon e avvia la definizione delle ECS attività Amazon o il EKS pod Amazon che hai creato, in us-east-1 Regione AWS. È solo durante questo processo di test, prima che il prodotto sia disponibile, che devi utilizzare questa regione.

  12. Quando ricevi una risposta valida daRegisterUsage, puoi iniziare a creare il tuo prodotto contenitore. Per domande, contatta il team Operativo Marketplace AWS del venditore.

RegisterUsage Esempio di Java

L'esempio seguente utilizza AWS SDK for Java and Marketplace AWS Metering Service per chiamare l'RegisterUsageoperazione. La verifica della firma è facoltativa, ma se si desidera eseguire la verifica della firma, è necessario includere le librerie di verifica delle firme digitali richieste. Questo esempio è solo a scopo illustrativo.

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(); } } }