Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAMEL-21875: add config for authorization headers #17494

Merged
merged 12 commits into from
Mar 30, 2025
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import org.apache.camel.component.as2.api.entity.MultipartMimeEntity;
import org.apache.camel.component.as2.api.protocol.RequestAsynchronousMDN;
import org.apache.camel.component.as2.api.util.AS2HeaderUtils;
import org.apache.camel.component.as2.api.util.EntityUtils;
import org.apache.camel.util.ObjectHelper;
import org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory;
Expand Down Expand Up @@ -89,14 +90,23 @@ public class AS2AsynchronousMDNManager {
private Certificate[] signingCertificateChain;
@SuppressWarnings("unused")
private PrivateKey signingPrivateKey;
private String userName;
private String password;
private String accessToken;

public AS2AsynchronousMDNManager(String as2Version,
String userAgent,
String senderFQDN,
Certificate[] signingCertificateChain,
PrivateKey signingPrivateKey) {
PrivateKey signingPrivateKey,
String userName,
String password,
String accessToken) {
this.signingCertificateChain = signingCertificateChain;
this.signingPrivateKey = signingPrivateKey;
this.userName = userName;
this.password = password;
this.accessToken = accessToken;

// Build Processor
httpProcessor = HttpProcessorBuilder.create().add(new RequestAsynchronousMDN(as2Version, senderFQDN))
Expand Down Expand Up @@ -131,6 +141,7 @@ public HttpCoreContext send(

ClassicHttpRequest request = new BasicClassicHttpRequest("POST", uri);
request.setHeader(AS2Header.CONTENT_TYPE, contentType);
AS2HeaderUtils.addAuthorizationHeader(request, userName, password, accessToken);
httpContext.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
multipartMimeEntity.setMainBody(true);
EntityUtils.setMessageEntity(request, multipartMimeEntity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.camel.component.as2.api.entity.ApplicationPkcs7MimeEnvelopedDataEntity;
import org.apache.camel.component.as2.api.entity.EntityParser;
import org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
import org.apache.camel.component.as2.api.util.AS2HeaderUtils;
import org.apache.camel.component.as2.api.util.CompressionUtils;
import org.apache.camel.component.as2.api.util.EncryptingUtils;
import org.apache.camel.component.as2.api.util.EntityUtils;
Expand Down Expand Up @@ -202,6 +203,10 @@ public AS2ClientManager(AS2ClientConnection as2ClientConnection) {
* if sending EDI message unencrypted
* @param attachedFileName - the name of the attached file or <code>null</code> if user doesn't want to
* specify it
* @param receiptDeliveryOption - the return URL that the message receiver should send an asynchronous MDN to
* @param userName - the user-name that is used for basic authentication
* @param password - the password that is used by the client for basic authentication
* @param accessToken - the access token that is used by the client for bearer authentication
* @return {@link HttpCoreContext} containing request and response used to send EDI
* message
* @throws HttpException when things go wrong.
Expand All @@ -226,7 +231,10 @@ public HttpCoreContext send(
AS2EncryptionAlgorithm encryptingAlgorithm,
Certificate[] encryptingCertificateChain,
String attachedFileName,
String receiptDeliveryOption)
String receiptDeliveryOption,
String userName,
String password,
String accessToken)
throws HttpException {

ObjectHelper.notNull(ediMessage, "EDI Message");
Expand Down Expand Up @@ -283,6 +291,8 @@ public HttpCoreContext send(
} catch (Exception e) {
throw new HttpException("Failed to create EDI message entity", e);
}

AS2HeaderUtils.addAuthorizationHeader(request, userName, password, accessToken);
switch (as2MessageStructure) {
case PLAIN: {
plain(applicationEntity, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,9 @@ public interface AS2Header {
* Message Header name for Disposition Notification Options
*/
String DISPOSITION_NOTIFICATION_OPTIONS = "Disposition-Notification-Options";
/**
* Message Header name for Authorization
*/
String AUTHORIZATION = "Authorization";

}
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ public void run() {
DispositionNotificationMultipartReportEntity.class);
AS2AsynchronousMDNManager asynchronousMDNManager = new AS2AsynchronousMDNManager(
as2Version,
originServer, serverFqdn, signingCertificateChain, signingPrivateKey);
originServer, serverFqdn, signingCertificateChain, signingPrivateKey,
userName, password, accessToken);

HttpRequest request = coreContext.getAttribute(HttpCoreContext.HTTP_REQUEST, HttpRequest.class);
AS2SignedDataGenerator gen = ResponseMDN.createSigningGenerator(
Expand Down Expand Up @@ -224,6 +225,9 @@ public void run() {
private final PrivateKey decryptingPrivateKey;
private final Certificate[] validateSigningCertificateChain;
private final AS2SignatureAlgorithm signingAlgorithm;
private final String userName;
private final String password;
private final String accessToken;

public AS2ServerConnection(String as2Version,
String originServer,
Expand All @@ -235,8 +239,11 @@ public AS2ServerConnection(String as2Version,
PrivateKey decryptingPrivateKey,
String mdnMessageTemplate,
Certificate[] validateSigningCertificateChain,
SSLContext sslContext)
throws IOException {
SSLContext sslContext,
String userName,
String password,
String accessToken)
throws IOException {
this.as2Version = ObjectHelper.notNull(as2Version, "as2Version");
this.originServer = ObjectHelper.notNull(originServer, "userAgent");
this.serverFqdn = ObjectHelper.notNull(serverFqdn, "serverFqdn");
Expand All @@ -245,6 +252,9 @@ public AS2ServerConnection(String as2Version,
this.signingPrivateKey = signingPrivateKey;
this.decryptingPrivateKey = decryptingPrivateKey;
this.validateSigningCertificateChain = validateSigningCertificateChain;
this.userName = userName;
this.password = password;
this.accessToken = accessToken;

this.signingAlgorithm = signingAlgorithm;
listenerThread = new RequestListenerThread(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import java.util.BitSet;
import java.util.List;

import org.apache.camel.component.as2.api.AS2Header;
import org.apache.camel.component.as2.api.entity.Importance;
import org.apache.camel.util.ObjectHelper;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HeaderElement;
import org.apache.hc.core5.http.HttpMessage;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.message.MessageSupport;
Expand Down Expand Up @@ -162,4 +164,12 @@ public static String getParameterValue(Header[] headers, String headerName, Stri
return null;
}

public static void addAuthorizationHeader(HttpMessage message, String userName, String password, String accessToken) {
if (userName != null && password != null) {
message.addHeader(AS2Header.AUTHORIZATION,
("Basic " + java.util.Base64.getEncoder().encodeToString((userName + ":" + password).getBytes())));
} else if (accessToken != null) {
message.addHeader(AS2Header.AUTHORIZATION, "Bearer " + accessToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static void setUpOnce() throws Exception {
testServer = new AS2ServerConnection(
AS2_VERSION, "MyServer-HTTP/1.1", SERVER_FQDN, TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA,
certList.toArray(new Certificate[0]), signingKP.getPrivate(), decryptingKP.getPrivate(), MDN_MESSAGE_TEMPLATE,
VALIDATE_SIGNING_CERTIFICATE_CHAIN, null);
VALIDATE_SIGNING_CERTIFICATE_CHAIN, null, null, null, null);
testServer.listen("*", new HttpRequestHandler() {
@Override
public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context)
Expand Down Expand Up @@ -171,7 +171,8 @@ public void multipartSignedMessageRequestTest() throws Exception {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.SIGNED, AS2MediaType.APPLICATION_EDIFACT, null,
null, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, "file.txt", null);
null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down Expand Up @@ -326,7 +327,8 @@ public void envelopedMessageTest(AS2EncryptionAlgorithm encryptionAlgorithm) thr
AS2MediaType.APPLICATION_EDIFACT, null, null,
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), null,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, encryptionAlgorithm,
certList.toArray(new Certificate[0]), "file.txt", null);
certList.toArray(new Certificate[0]), "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down Expand Up @@ -383,7 +385,8 @@ public void envelopedAndSignedMessageTest(AS2EncryptionAlgorithm encryptionAlgor
AS2MediaType.APPLICATION_EDIFACT, null, null,
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(), null,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, encryptionAlgorithm,
certList.toArray(new Certificate[0]), "file.txt", null);
certList.toArray(new Certificate[0]), "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down Expand Up @@ -446,7 +449,8 @@ public void signatureVerificationTest() throws Exception {
HttpCoreContext httpContext = clientManager.send(EDI_MESSAGE, REQUEST_URI, SUBJECT, FROM, AS2_NAME, AS2_NAME,
AS2MessageStructure.SIGNED, AS2MediaType.APPLICATION_EDIFACT, null,
null, AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, "file.txt", null);
null, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null, "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertTrue(request instanceof ClassicHttpRequest, "Request does not contain entity");
Expand All @@ -471,7 +475,7 @@ public void asynchronousMdnMessageTest() throws Exception {

AS2AsynchronousMDNManager mdnManager = new AS2AsynchronousMDNManager(
AS2_VERSION, USER_AGENT, CLIENT_FQDN,
certList.toArray(new X509Certificate[0]), signingKP.getPrivate());
certList.toArray(new X509Certificate[0]), signingKP.getPrivate(), null, null, null);

// Create plain edi request message to acknowledge
ApplicationEntity ediEntity = EntityUtils.createEDIEntity(EDI_MESSAGE.getBytes(StandardCharsets.US_ASCII),
Expand Down Expand Up @@ -559,7 +563,8 @@ private void signedAndCompressedMessage(Object msg) throws Exception {
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
AS2CompressionAlgorithm.ZLIB,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null,
null, "file.txt", null);
null, "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down Expand Up @@ -632,7 +637,8 @@ private void envelopedAndCompressedMessage(Object msg) throws Exception {
AS2MessageStructure.ENCRYPTED_COMPRESSED,
AS2MediaType.APPLICATION_EDIFACT, null, "base64", null, null, null,
AS2CompressionAlgorithm.ZLIB, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS,
AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]), "file.txt", null);
AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]), "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down Expand Up @@ -703,7 +709,8 @@ private void compressedAndSignedMessage(Object msg) throws Exception {
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
AS2CompressionAlgorithm.ZLIB,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null,
null, "file.txt", null);
null, "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
verifyRequest(request);
Expand Down Expand Up @@ -738,7 +745,8 @@ private void envelopedSignedAndCompressedMessage(Object msg) throws Exception {
AS2MediaType.APPLICATION_EDIFACT, null, null,
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
AS2CompressionAlgorithm.ZLIB, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS,
AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]), "file.txt", null);
AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]), "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
verifyRequest(request);
Expand Down Expand Up @@ -783,7 +791,8 @@ private void envelopedCompressedAndSignedMessage(Object msg) throws Exception {
AS2MediaType.APPLICATION_EDIFACT, null, null,
AS2SignatureAlgorithm.SHA256WITHRSA, certList.toArray(new Certificate[0]), signingKP.getPrivate(),
AS2CompressionAlgorithm.ZLIB, DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS,
AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]), "file.txt", null);
AS2EncryptionAlgorithm.AES128_CBC, certList.toArray(new Certificate[0]), "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public static void setUpOnce() throws Exception {
testServer = new AS2ServerConnection(
AS2_VERSION, "MyServer-HTTP/1.1", SERVER_FQDN, TARGET_PORT, AS2SignatureAlgorithm.SHA256WITHRSA,
certList.toArray(new Certificate[0]), signingKP.getPrivate(), null, MDN_MESSAGE_TEMPLATE,
null, null);
null, null, null, null, null);
testServer.listen("*", new HttpRequestHandler() {
@Override
public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context)
Expand All @@ -87,7 +87,7 @@ public void plainEDIMessageRequestTest() throws Exception {
AS2MessageStructure.PLAIN, AS2MediaType.APPLICATION_EDIFACT, null,
null, null, null, null, null,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null,
"file.txt", null);
"file.txt", null, null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down Expand Up @@ -128,7 +128,8 @@ public void compressedMessageRequestTest() throws Exception {
AS2MediaType.APPLICATION_EDIFACT, null, null,
null, null, null, AS2CompressionAlgorithm.ZLIB,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null,
null, "file.txt", null);
null, "file.txt", null,
null, null, null);

HttpRequest request = httpContext.getRequest();
assertEquals(METHOD, request.getMethod(), "Unexpected method value");
Expand Down Expand Up @@ -175,7 +176,7 @@ public void mdnMessageTest() throws Exception {
AS2MessageStructure.PLAIN, AS2MediaType.APPLICATION_EDIFACT, null,
null, null, null, null, null,
DISPOSITION_NOTIFICATION_TO, SIGNED_RECEIPT_MIC_ALGORITHMS, null, null,
"file.txt", null);
"file.txt", null, null, null, null);

HttpResponse response = httpContext.getResponse();
assertEquals(HttpVersion.HTTP_1_1, response.getVersion(), "Unexpected method value");
Expand Down
3 changes: 3 additions & 0 deletions components/camel-as2/camel-as2-component/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
<nullableOption>attachedFileName</nullableOption>
<nullableOption>receiptDeliveryOption</nullableOption>
<nullableOption>ediMessageCharset</nullableOption>
<nullableOption>userName</nullableOption>
<nullableOption>password</nullableOption>
<nullableOption>accessToken</nullableOption>
</nullableOptions>
</api>
<api>
Expand Down
Loading
Loading