-
Notifications
You must be signed in to change notification settings - Fork 41
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
feat(rest-connector): Add support for proxy auth #3894
base: main
Are you sure you want to change the base?
Conversation
|
||
# Allow unauthenticated users on /path | ||
acl no_auth_url url_regex -i path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so with this setting every path is needs username and password except "/path". I would rather have only "/protected" be protected and everything else allowed, but I am not sure if this is possible. So if you have an idea let me know.
.../http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
Fixed
Show fixed
Hide fixed
.../http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
Fixed
Show fixed
Hide fixed
@ztefanie We currently only document environment variables for our component configuration and we should therefore continue to support using them also for this use-case: https://docs.camunda.io/docs/next/self-managed/connectors-deployment/connectors-configuration/ |
.../http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
Outdated
Show resolved
Hide resolved
.../http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
Outdated
Show resolved
Hide resolved
|
||
private void setFromEnvVars() { | ||
host = System.getenv("CONNECTOR_" + protocol.toUpperCase() + "_PROXY_HOST"); | ||
port = Integer.parseInt(System.getenv("CONNECTOR_" + protocol.toUpperCase() + "_PROXY_PORT")); |
Check notice
Code scanning / CodeQL
Missing catch of NumberFormatException Note
|
||
private void setFromSystemProperties() { | ||
host = System.getProperty(protocol + ".proxyHost"); | ||
port = Integer.parseInt(System.getProperty(protocol + ".proxyPort")); |
Check notice
Code scanning / CodeQL
Missing catch of NumberFormatException Note
sourceIsSystemProperties = true; | ||
} | ||
|
||
public CredentialsProvider getCredentialsProvider(String uncheckedProtocol) { |
Check notice
Code scanning / CodeQL
Useless parameter Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI 3 days ago
To fix the problem, we need to remove the unused parameter uncheckedProtocol
from the getCredentialsProvider
method. This involves:
- Removing the parameter from the method signature.
- Updating any calls to this method to no longer pass this parameter.
This change should be made in the file connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
.
-
Copy modified line R68
@@ -67,3 +67,3 @@ | ||
|
||
public CredentialsProvider getCredentialsProvider(String uncheckedProtocol) { | ||
public CredentialsProvider getCredentialsProvider() { | ||
BasicCredentialsProvider provider = new BasicCredentialsProvider(); |
return provider; | ||
} | ||
|
||
public HttpHost getProxyHost(String uncheckedProtocol, String requestUri) { |
Check notice
Code scanning / CodeQL
Useless parameter Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI 3 days ago
To fix the problem, we should remove the unused requestUri
parameter from the getProxyHost
method. This will simplify the method signature and eliminate any confusion about the necessity of the parameter.
- Remove the
requestUri
parameter from thegetProxyHost
method signature. - Update any calls to the
getProxyHost
method to remove therequestUri
argument.
-
Copy modified line R79
@@ -78,3 +78,3 @@ | ||
|
||
public HttpHost getProxyHost(String uncheckedProtocol, String requestUri) { | ||
public HttpHost getProxyHost(String uncheckedProtocol) { | ||
return host == null |
: new HttpHost(fallbackOnHttpForInvalidProtocol(uncheckedProtocol), host, port); | ||
} | ||
|
||
private boolean doesTargetMatchNonProxy(String protocol, String requestUri) { |
Check notice
Code scanning / CodeQL
Useless parameter Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI 3 days ago
To fix the problem, we need to remove the unused protocol
parameter from the doesTargetMatchNonProxy
method. This involves updating the method signature and any calls to this method to exclude the protocol
parameter. This change will simplify the method's interface and eliminate the unnecessary parameter.
-
Copy modified line R35 -
Copy modified line R85
@@ -34,3 +34,3 @@ | ||
setFromEnvVars(); | ||
if (doesTargetMatchNonProxy(protocol, requestUrl)) { | ||
if (doesTargetMatchNonProxy(requestUrl)) { | ||
host = null; | ||
@@ -84,3 +84,3 @@ | ||
|
||
private boolean doesTargetMatchNonProxy(String protocol, String requestUri) { | ||
private boolean doesTargetMatchNonProxy(String requestUri) { | ||
return (nonProxyHosts != null |
requestUri.matches(nonProxyHost.replace(".", "\\.").replace("*", ".*")))); | ||
} | ||
|
||
public HttpRoutePlanner getRoutePlanner(String uncheckedProtocol, HttpHost proxyHost) { |
Check notice
Code scanning / CodeQL
Useless parameter Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI 3 days ago
To fix the problem, we need to remove the unused parameter uncheckedProtocol
from the method getRoutePlanner
. This involves updating the method signature and ensuring that any calls to this method are also updated to remove the unnecessary argument.
- Remove the
uncheckedProtocol
parameter from thegetRoutePlanner
method signature. - Update any calls to
getRoutePlanner
to no longer pass theuncheckedProtocol
argument.
-
Copy modified line R93
@@ -92,3 +92,3 @@ | ||
|
||
public HttpRoutePlanner getRoutePlanner(String uncheckedProtocol, HttpHost proxyHost) { | ||
public HttpRoutePlanner getRoutePlanner(HttpHost proxyHost) { | ||
if (sourceIsSystemProperties) { |
ProxyHandler proxyHandler = | ||
new ProxyHandler(apacheRequest.getScheme(), apacheRequest.getUri().getHost()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we are creating a new proxy handler for every new request. I think this should be done once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Moved it to HttpClient
BasicCredentialsProvider provider = new BasicCredentialsProvider(); | ||
if (StringUtils.isNotBlank(host) | ||
&& StringUtils.isNotBlank(user) | ||
&& ArrayUtils.isNotEmpty(password)) { | ||
provider.setCredentials( | ||
new AuthScope(host, port), new UsernamePasswordCredentials(user, password)); | ||
} | ||
return provider; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the password or another entry is empty? Should we log a warning or something?
Otherwise this will silently lead to a credentials provider without credentials.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if password or another entry is empty a credentials provider without credentials is created. This is expected and wanted behavior, because some proxy do not require credentials. Requests to these proxies are than handled without crendentials with success. If no credentials are provided, but expected by the proxy, the execution will fail with "Proxy Authentication required" error.
if (sourceIsSystemProperties) { | ||
return new SystemDefaultRoutePlanner( | ||
DefaultSchemePortResolver.INSTANCE, ProxySelector.getDefault()); | ||
} else if (proxyHost != null) { | ||
return new DefaultProxyRoutePlanner(proxyHost); | ||
} | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to add some debug logs here. Otherwise it might be intransparent which config was applied.
Description
Added support for setting proxy via env var and to add proxy auth.
Proxy config can be set via system properties or via env vars. Setting via env vars is currently handled by using an RFC3986 string, e.g. http://my-user:demo@localhost:3128/
This means it is currently not possible to set nonProxyHosts via env vars and username and passwords must be url safe.
I think we could also change this, with some effort, to setting multiple env vars. I decided to go for this version, assuming setting via env vars is more for testing / fast setups, but not complex production setups, as setting passwords in ENV vars is worse than setting in system properties. If you disagree please let me know, then i will adjust it.
I tested different use cases manually, with the following results:
![image](https://private-user-images.githubusercontent.com/18463686/409562819-26061410-9f9b-40ce-b9dd-760949ab6ed0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkxOTE5MjYsIm5iZiI6MTczOTE5MTYyNiwicGF0aCI6Ii8xODQ2MzY4Ni80MDk1NjI4MTktMjYwNjE0MTAtOWY5Yi00MGNlLWI5ZGQtNzYwOTQ5YWI2ZWQwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTAlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEwVDEyNDcwNlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWJmZTQ1MDE0MTZmYjliYzNlNjM2Yjg3Y2U4OWI2M2E2N2YxM2VjMmMwYzA0YzNkYThkYjllNzQ5ZmEzMWYyNDImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.BKK5hZSaDKt0Nwi91gxp-GrZ0jUn_vYGma0JkiILlkY)
I tried to add Unit tests for nonProxyHosts but couldn't get it working as mocking only one host / localhost is possible with Wiremock. If you think nonProxyHost unit test should be added, please give me a hint how to achieve this.
Not tested for https.
I will add this to the docs, once this is approved or at least we agreed on how to set it with env vars.
Related issues
closes https://github.com/camunda/team-connectors/issues/989
Checklist
no milestone
label.