Class SignatureRequestBuilder

java.lang.Object
io.fliqa.client.interledger.signature.SignatureRequestBuilder

public class SignatureRequestBuilder extends Object
Builder for creating cryptographically signed HTTP requests for Interledger API communication.

This class implements the HTTP Message Signatures specification (RFC 9421) to create signed HTTP requests that ensure authenticity and integrity when communicating with Interledger Open Payments servers. All requests are signed using Ed25519 cryptographic signatures.

Signature Process

The signing process involves several steps:

  1. Request Building - Set HTTP method, target URI, and request body
  2. Header Generation - Calculate content digest, length, and authorization
  3. Signature Base - Create signature base from headers and metadata
  4. Signing - Generate Ed25519 signature of the signature base
  5. Header Assembly - Add signature and signature input headers

Supported Features

  • Ed25519 digital signatures for request authentication
  • SHA-512 content digest calculation for request integrity
  • Support for GET, POST, PUT, DELETE, and HEAD methods
  • JSON request body serialization and content-type handling
  • Bearer token authorization with GNAP format
  • Configurable request timeouts

Usage Example


 SignatureRequestBuilder builder = new SignatureRequestBuilder(privateKey, keyId)
     .POST(requestBody)
     .target("https://api.example.com/payments")
     .accessToken("example-access-token")
     .build();

 HttpRequest signedRequest = builder.getRequest(clientOptions);
 

Security Considerations

  • Private keys should be securely stored and not logged
  • Signatures include timestamps to prevent replay attacks
  • Content digests ensure request body integrity
  • All signature parameters are included in the signature calculation
Since:
1.0
See Also:
  • Field Details

  • Constructor Details

    • SignatureRequestBuilder

      public SignatureRequestBuilder(PrivateKey privateKey, String keyId, InterledgerObjectMapper mapper)
      Creates a new signature request builder with custom JSON mapper.
      Parameters:
      privateKey - Ed25519 private key for signing requests (must not be null)
      keyId - identifier for the private key (must not be null or blank)
      mapper - JSON mapper for serializing objects, uses default if null
      Throws:
      AssertionError - if privateKey is null or keyId is null/blank
    • SignatureRequestBuilder

      public SignatureRequestBuilder(PrivateKey privateKey, String keyId)
      Creates a new signature request builder with the default JSON mapper.
      Parameters:
      privateKey - Ed25519 private key for signing requests (must not be null)
      keyId - identifier for the private key (must not be null or blank)
      Throws:
      AssertionError - if privateKey is null or keyId is null/blank
  • Method Details

    • method

      public SignatureRequestBuilder method(String value)
      Sets the HTTP method for the request.
      Parameters:
      value - HTTP method (GET, POST, PUT, DELETE, HEAD)
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if method is null, blank, or not allowed
    • POST

      public SignatureRequestBuilder POST(Object body)
      Sets the request method to POST and serializes the body as JSON.
      Parameters:
      body - object to serialize as JSON request body
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if method is already set or body serialization fails
    • POST

      public SignatureRequestBuilder POST()
      Sets the HTTP method for the request to POST without the request body.
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if the method is already set
    • PUT

      public SignatureRequestBuilder PUT(Object body)
      Sets the HTTP method for the request to PUT and serializes the body as JSON.
      Parameters:
      body - the object to serialize as the JSON request body
      Returns:
      this builder instance for method chaining
      Throws:
      IllegalArgumentException - if the method is already set or if body serialization fails
    • PUT

      Sets the HTTP method for the request to PUT without the request body.
      Returns:
      this builder instance for method chaining
      Throws:
      IllegalArgumentException - if the method is already set
    • GET

      Sets the request method to GET.
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if the method is already set
    • DELETE

      public SignatureRequestBuilder DELETE()
      Set the request method to DELETE.
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if the method is already set
    • getMethod

      public String getMethod()
      Gets the configured HTTP method.
      Returns:
      the HTTP method (GET, POST, PUT, DELETE, HEAD)
      Throws:
      IllegalArgumentException - if the method has not been set
    • target

      public SignatureRequestBuilder target(String value)
      Sets the target URI for the signature request.
      Parameters:
      value - the target URI as a string
      Returns:
      the updated SignatureRequestBuilder instance
    • target

      public SignatureRequestBuilder target(URI value)
      Sets the target URI for the request.

      The URI is normalized to ensure it ends with '/' when no query parameters are present, as required by the signature specification.

      Parameters:
      value - target URI for the HTTP request
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if URI is null
    • json

      public SignatureRequestBuilder json(Object object)
      Sets the request body by serializing an object to JSON.

      This method automatically serializes the provided object to JSON using the configured ObjectMapper and then calls json(String) to set all required headers.

      Parameters:
      object - object to serialize as JSON request body
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if object serialization fails
    • json

      public SignatureRequestBuilder json(String json)
      Sets the request body as JSON and calculates required headers.

      This method automatically:

      • Sets Content-Type to application/json
      • Calculates Content-Length header
      • Generates SHA-512 Content-Digest header
      Parameters:
      json - JSON string to set as the request body
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if JSON is null or empty
    • accessToken

      public SignatureRequestBuilder accessToken(String token)
      Sets the access token for authorization.

      The token is formatted as a GNAP (Grant Negotiation and Authorization Protocol) bearer token in the Authorization header.

      Parameters:
      token - access token for API authorization
      Returns:
      this builder for method chaining
      Throws:
      IllegalArgumentException - if the token is null or empty
    • build

      public SignatureRequestBuilder build()
      Builds the signature using the current timestamp.

      This method should be called after all request parameters have been set and before retrieving headers or creating the HTTP request. It generates the signature parameters and prepares the builder for signature calculation.

      Returns:
      this builder for method chaining
    • build

      public SignatureRequestBuilder build(long createdInSeconds)
      Builds the signature using a specific timestamp.

      This method allows setting a custom timestamp for signature creation, which is useful for testing or when you need precise control over the signature timestamp for replay attack prevention.

      Parameters:
      createdInSeconds - Unix timestamp in seconds when the signature was created
      Returns:
      this builder for method chaining
    • getTarget

      public URI getTarget()
      Gets the configured target URI.
      Returns:
      the target URI for the HTTP request
      Throws:
      IllegalArgumentException - if target has not been set
    • getSignatureParamsHeader

      public String getSignatureParamsHeader()
      Constructs and returns the signature parameters header as a formatted string.

      The method validates the state before retrieving the signature parameters from the parameters map using the key SIGNATURE_PARAMS. Then, it formats and returns the signature identifier and the retrieved parameters as a string.

      Returns:
      the signature parameters header in the format "DEFAULT_SIGNATURE_ID=signatureParams".
    • getSignatureBase

      protected String getSignatureBase()
      Provide base for signature calculation
      Returns:
      signature base input
    • digestContentSha512

      protected static String digestContentSha512(String content) throws NoSuchAlgorithmException
      Calculates SHA-512 content digest for request body integrity.

      This method generates a SHA-512 hash of the content and returns it as a Base64-encoded string. The content digest is used to ensure that the request body has not been tampered with during transmission.

      Parameters:
      content - request body content to create digest for
      Returns:
      Base64-encoded SHA-512 digest of the content
      Throws:
      IllegalArgumentException - if content is null or empty
      NoSuchAlgorithmException - if SHA-512 algorithm is not available
    • getSignature

      protected String getSignature()
      Returns signature Base64 encoded Signature is generated from a signature base consisting of the header names and values of the request
      Returns:
      signature of request to be added as request header
    • getHeaders

      public LinkedHashMap<String,String> getHeaders()
      Gets all HTTP headers for the signed request.

      This method returns all headers required for the signed request including:

      • Accept header (application/json)
      • Content-Type header (if body is present)
      • Content-Digest header (if body is present)
      • Authorization header (if access token is set)
      • Signature-Input header with signature parameters
      • Signature header with the actual signature
      Returns:
      ordered map of HTTP headers for the request
      Throws:
      IllegalStateException - if signature has not been built yet
    • getBody

      public String getBody()
      Retrieves the JSON body of the HTTP request.
      Returns:
      the request body as a string, or null if no body is set
    • getRequest

      public HttpRequest getRequest(InterledgerClientOptions options)
      Creates a fully signed HTTP request from all configured parameters.

      This method combines all the configured parameters, headers, and signature information to create a complete HTTP request ready for execution. If the signature has not been built yet, it will be built automatically.

      Parameters:
      options - client configuration including request timeouts
      Returns:
      signed HTTP request ready for execution
    • getBuilder

      public HttpRequest.Builder getBuilder(InterledgerClientOptions options)
      Constructs and returns an HttpRequest.Builder object based on the configured parameters, headers, and body. If the required signature parameters are not built, they will be initialized before creating the builder.
      Parameters:
      options - The InterledgerClientOptions containing the timeout configuration for the request.
      Returns:
      An HttpRequest.Builder instance configured with the appropriate target URI, HTTP method, headers, body, and timeout.