More fixes
This commit is contained in:
parent
3fa67c43d6
commit
96cf1fe5ad
3 changed files with 39 additions and 12 deletions
|
|
@ -197,6 +197,23 @@ public class HttpSignatureValidator {
|
||||||
return Base64.getEncoder().encodeToString(signature);
|
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.
|
* Signs an outbound HTTP request for ActivityPub federation.
|
||||||
*
|
*
|
||||||
|
|
@ -205,9 +222,9 @@ public class HttpSignatureValidator {
|
||||||
* @param body the request body
|
* @param body the request body
|
||||||
* @param privateKeyPem the sender's private key
|
* @param privateKeyPem the sender's private key
|
||||||
* @param keyId the public key ID
|
* @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 {
|
try {
|
||||||
java.net.URI uri = new java.net.URI(targetUrl);
|
java.net.URI uri = new java.net.URI(targetUrl);
|
||||||
String host = uri.getHost();
|
String host = uri.getHost();
|
||||||
|
|
@ -239,11 +256,13 @@ public class HttpSignatureValidator {
|
||||||
String signatureBase64 = sign(signingString, privateKeyPem);
|
String signatureBase64 = sign(signingString, privateKeyPem);
|
||||||
|
|
||||||
// Build signature header
|
// Build signature header
|
||||||
return String.format(
|
String signatureHeader = String.format(
|
||||||
"keyId=\"%s\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"%s\"",
|
"keyId=\"%s\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"%s\"",
|
||||||
keyId, signatureBase64
|
keyId, signatureBase64
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return new SignatureHeaders(host, date, digestValue, signatureHeader);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to sign request", e);
|
log.error("Failed to sign request", e);
|
||||||
throw new RuntimeException("Failed to sign request", e);
|
throw new RuntimeException("Failed to sign request", e);
|
||||||
|
|
|
||||||
|
|
@ -166,19 +166,24 @@ public class FederationService {
|
||||||
try {
|
try {
|
||||||
String activityJson = objectMapper.writeValueAsString(activity);
|
String activityJson = objectMapper.writeValueAsString(activity);
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
// Generate HTTP signature with all required headers
|
||||||
headers.set("Content-Type", "application/activity+json");
|
HttpSignatureValidator.SignatureHeaders signatureHeaders = signatureValidator.signRequest(
|
||||||
headers.set("Accept", "application/activity+json");
|
|
||||||
|
|
||||||
// Add HTTP signature
|
|
||||||
String signature = signatureValidator.signRequest(
|
|
||||||
HttpMethod.POST.name(),
|
HttpMethod.POST.name(),
|
||||||
inboxUrl,
|
inboxUrl,
|
||||||
activityJson,
|
activityJson,
|
||||||
sender.getPrivateKey(),
|
sender.getPrivateKey(),
|
||||||
baseUrl + "/users/" + sender.getUsername() + "#main-key"
|
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);
|
HttpEntity<String> entity = new HttpEntity<>(activityJson, headers);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@
|
||||||
# Activated with: mvn spring-boot:run -Dspring-boot.run.profiles=dev
|
# Activated with: mvn spring-boot:run -Dspring-boot.run.profiles=dev
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
# Development datasource is handled by Testcontainers (see TestcontainersConfiguration)
|
datasource:
|
||||||
# No need to configure datasource here - it's automatically configured
|
url: jdbc:postgresql://localhost:5432/fitpub
|
||||||
|
username: fitpub
|
||||||
|
password: change_me_in_production
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue