More fixes

This commit is contained in:
Tim Zöller 2025-11-29 22:00:35 +01:00
parent 3fa67c43d6
commit 96cf1fe5ad
3 changed files with 39 additions and 12 deletions

View file

@ -197,6 +197,23 @@ public class HttpSignatureValidator {
return Base64.getEncoder().encodeToString(signature);
}
/**
* Container for HTTP signature headers.
*/
public static class SignatureHeaders {
public final String host;
public final String date;
public final String digest;
public final String signature;
public SignatureHeaders(String host, String date, String digest, String signature) {
this.host = host;
this.date = date;
this.digest = digest;
this.signature = signature;
}
}
/**
* Signs an outbound HTTP request for ActivityPub federation.
*
@ -205,9 +222,9 @@ public class HttpSignatureValidator {
* @param body the request body
* @param privateKeyPem the sender's private key
* @param keyId the public key ID
* @return the Signature header value
* @return SignatureHeaders containing all headers needed for the signed request
*/
public String signRequest(String method, String targetUrl, String body, String privateKeyPem, String keyId) {
public SignatureHeaders signRequest(String method, String targetUrl, String body, String privateKeyPem, String keyId) {
try {
java.net.URI uri = new java.net.URI(targetUrl);
String host = uri.getHost();
@ -239,11 +256,13 @@ public class HttpSignatureValidator {
String signatureBase64 = sign(signingString, privateKeyPem);
// Build signature header
return String.format(
String signatureHeader = String.format(
"keyId=\"%s\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"%s\"",
keyId, signatureBase64
);
return new SignatureHeaders(host, date, digestValue, signatureHeader);
} catch (Exception e) {
log.error("Failed to sign request", e);
throw new RuntimeException("Failed to sign request", e);

View file

@ -166,19 +166,24 @@ public class FederationService {
try {
String activityJson = objectMapper.writeValueAsString(activity);
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/activity+json");
headers.set("Accept", "application/activity+json");
// Add HTTP signature
String signature = signatureValidator.signRequest(
// Generate HTTP signature with all required headers
HttpSignatureValidator.SignatureHeaders signatureHeaders = signatureValidator.signRequest(
HttpMethod.POST.name(),
inboxUrl,
activityJson,
sender.getPrivateKey(),
baseUrl + "/users/" + sender.getUsername() + "#main-key"
);
headers.set("Signature", signature);
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/activity+json");
headers.set("Accept", "application/activity+json");
// Add all signature-related headers
headers.set("Host", signatureHeaders.host);
headers.set("Date", signatureHeaders.date);
headers.set("Digest", signatureHeaders.digest);
headers.set("Signature", signatureHeaders.signature);
HttpEntity<String> entity = new HttpEntity<>(activityJson, headers);

View file

@ -2,8 +2,11 @@
# Activated with: mvn spring-boot:run -Dspring-boot.run.profiles=dev
spring:
# Development datasource is handled by Testcontainers (see TestcontainersConfiguration)
# No need to configure datasource here - it's automatically configured
datasource:
url: jdbc:postgresql://localhost:5432/fitpub
username: fitpub
password: change_me_in_production
driver-class-name: org.postgresql.Driver
jpa:
hibernate: