Implementation:Apache Paimon DLFDefaultSigner
| Knowledge Sources | |
|---|---|
| Domains | Authentication, Cryptography, Request Signing |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
DLFDefaultSigner implements the default DLF VPC endpoint authentication protocol using HMAC-SHA256 signature calculation.
Description
DLFDefaultSigner is a concrete implementation of the DLFRequestSigner interface that provides signature-based authentication for Alibaba Cloud Data Lake Formation's default VPC endpoint. It implements the DLF4-HMAC-SHA256 signing algorithm, which is the standard authentication protocol for traditional DLF endpoints.
The signing process involves multiple cryptographic operations and careful construction of canonical request strings. First, the signer generates required headers including the request timestamp in ISO 8601 format, content MD5 hash for POST requests, content SHA-256 hash (or UNSIGNED-PAYLOAD marker), and security token if using temporary credentials. These headers are critical for ensuring request integrity and preventing replay attacks.
The authorization calculation follows a multi-step process: constructing a canonical request from the HTTP method, resource path, sorted query parameters, and sorted signed headers; creating a string-to-sign that includes the signature algorithm identifier, timestamp, credential scope, and hashed canonical request; deriving a signing key through multiple HMAC-SHA256 operations on the date, region, product code, and request type; and finally computing the final signature by applying HMAC-SHA256 to the string-to-sign using the derived key.
The implementation carefully handles header sorting and normalization, ensuring consistent signature generation across different requests. It supports various HTTP methods and properly includes query parameters and request bodies in the signature calculation to prevent tampering. The signer is designed for backward compatibility with existing DLF deployments using the traditional VPC endpoint architecture.
Usage
Use DLFDefaultSigner when authenticating requests to traditional Alibaba Cloud DLF VPC endpoints that use the DLF4-HMAC-SHA256 signing protocol. This signer is automatically selected when the signing algorithm is set to "default" or when auto-detection determines the endpoint is not a DlfNext OpenAPI endpoint.
Code Reference
Source Location
- Repository: Apache_Paimon
- File: paimon-api/src/main/java/org/apache/paimon/rest/auth/DLFDefaultSigner.java
Signature
public class DLFDefaultSigner implements DLFRequestSigner {
public static final String IDENTIFIER = "default";
public static final String VERSION = "v1";
private static final String SIGNATURE_ALGORITHM = "DLF4-HMAC-SHA256";
private static final String PRODUCT = "DlfNext";
private static final String HMAC_SHA256 = "HmacSHA256";
private static final String REQUEST_TYPE = "aliyun_v4_request";
private final String region;
public DLFDefaultSigner(String region);
@Override
public Map<String, String> signHeaders(
@Nullable String body, Instant now, @Nullable String securityToken, String host);
@Override
public String authorization(
RESTAuthParameter restAuthParameter,
DLFToken token,
String host,
Map<String, String> signHeaders) throws Exception;
@Override
public String identifier();
}
Import
import org.apache.paimon.rest.auth.DLFDefaultSigner;
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| region | String | Yes | Alibaba Cloud region identifier |
| body | String | No | Request body for signature calculation |
| now | Instant | Yes | Current timestamp for date headers |
| securityToken | String | No | Security token for temporary credentials |
| host | String | Yes | Host value for signature calculation |
| restAuthParameter | RESTAuthParameter | Yes | Request parameters (path, method, query params, data) |
| token | DLFToken | Yes | DLF token containing access key ID and secret |
| signHeaders | Map<String, String> | Yes | Headers generated by signHeaders() method |
Outputs
| Name | Type | Description |
|---|---|---|
| signHeaders() | Map<String, String> | Returns headers including x-dlf-date, x-dlf-version, Content-MD5, etc. |
| authorization() | String | Returns Authorization header value with signature |
| identifier() | String | Returns "default" as the signer identifier |
Usage Examples
import org.apache.paimon.rest.auth.DLFDefaultSigner;
import org.apache.paimon.rest.auth.DLFToken;
import org.apache.paimon.rest.auth.RESTAuthParameter;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
// Example 1: Create signer for region
DLFDefaultSigner signer = new DLFDefaultSigner("cn-hangzhou");
// Example 2: Generate sign headers for GET request
Instant now = Instant.now();
Map<String, String> signHeaders = signer.signHeaders(
null, // no body for GET
now,
null, // no security token
"dlf.cn-hangzhou.aliyuncs.com"
);
// Sign headers include:
// x-dlf-date: 20260208T120000Z
// x-dlf-content-sha256: UNSIGNED-PAYLOAD
// x-dlf-version: v1
// Example 3: Generate sign headers for POST request with body
String requestBody = "{\"name\":\"my_table\"}";
Map<String, String> postHeaders = signer.signHeaders(
requestBody,
now,
null,
"dlf.cn-hangzhou.aliyuncs.com"
);
// Additional headers for POST:
// Content-Type: application/json
// Content-MD5: <base64-encoded-md5-of-body>
// Example 4: Generate sign headers with security token (STS)
Map<String, String> stsHeaders = signer.signHeaders(
null,
now,
"STS_security_token_value",
"dlf.cn-hangzhou.aliyuncs.com"
);
// Additional header:
// x-dlf-security-token: STS_security_token_value
// Example 5: Generate authorization header
DLFToken token = new DLFToken("LTAI***", "secret***", null, null);
RESTAuthParameter authParam = new RESTAuthParameter(
"/api/v1/tables",
new HashMap<>(),
"GET",
""
);
String authorization = signer.authorization(
authParam,
token,
"dlf.cn-hangzhou.aliyuncs.com",
signHeaders
);
// Authorization format:
// DLF4-HMAC-SHA256 Credential=LTAI***/20260208/cn-hangzhou/DlfNext/aliyun_v4_request,
// Signature=<calculated-signature>
// Example 6: Complete signing workflow
public Map<String, String> signRequest(
String method,
String path,
Map<String, String> queryParams,
String body,
DLFToken token,
String region,
String host) throws Exception {
DLFDefaultSigner signer = new DLFDefaultSigner(region);
Instant now = Instant.now();
// Step 1: Generate sign headers
Map<String, String> signHeaders = signer.signHeaders(
body,
now,
token.getSecurityToken(),
host
);
// Step 2: Create auth parameter
RESTAuthParameter authParam = new RESTAuthParameter(
path,
queryParams,
method,
body
);
// Step 3: Generate authorization
String authorization = signer.authorization(
authParam,
token,
host,
signHeaders
);
// Step 4: Combine all headers
Map<String, String> allHeaders = new HashMap<>(signHeaders);
allHeaders.put("Authorization", authorization);
return allHeaders;
}
// Example 7: POST request with query parameters
Map<String, String> queryParams = new HashMap<>();
queryParams.put("namespace", "default");
queryParams.put("createMode", "overwrite");
String postBody = "{\"schema\":{...}}";
Map<String, String> headers = signRequest(
"POST",
"/api/v1/tables/my_table",
queryParams,
postBody,
token,
"cn-hangzhou",
"dlf.cn-hangzhou.aliyuncs.com"
);
// Example 8: DELETE request
Map<String, String> deleteHeaders = signRequest(
"DELETE",
"/api/v1/tables/my_table",
new HashMap<>(),
"",
token,
"cn-hangzhou",
"dlf.cn-hangzhou.aliyuncs.com"
);
// Example 9: Request with special characters in path
Map<String, String> specialHeaders = signRequest(
"GET",
"/api/v1/tables/my_table$partition", // Contains special character
new HashMap<>(),
"",
token,
"cn-hangzhou",
"dlf.cn-hangzhou.aliyuncs.com"
);
// Example 10: Multi-region support
DLFDefaultSigner beijingSigner = new DLFDefaultSigner("cn-beijing");
DLFDefaultSigner shanghaiSigner = new DLFDefaultSigner("cn-shanghai");
// Each signer includes the correct region in credential scope:
// cn-beijing: .../20260208/cn-beijing/DlfNext/...
// cn-shanghai: .../20260208/cn-shanghai/DlfNext/...