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

FISH-230: specify certificate alias for MP rest client and MP config #5445

Conversation

breakponchito
Copy link
Contributor

@breakponchito breakponchito commented Oct 11, 2021

Description

Adding support for custom configuration of sslContext using certificate alias property

Important Info

Blockers

Testing

New tests

Testing Performed

unit test and manual test documented here: (pending documentation and update of the wiki about design)
I added mock testing for the class

Testing Environment

Windows 10, JDK 8

Documentation

Pending documentation on the wiki page for the user view section: https://payara.atlassian.net/wiki/spaces/PAYAR/pages/3033006087/Feature+Design+-+Provide+Means+to+Specify+a+Certificate+Alias+for+JAX-RS+and+MP+REST+Client

Notes for Reviewers

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@Pandrex247
Copy link
Member

Jenkins test please


<artifactId>rest-client-ssl</artifactId>
<packaging>glassfish-jar</packaging>
<name>Rest Client ssl context</name>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pendantry - capitals

Suggested change
<name>Rest Client ssl context</name>
<name>Rest Client SSL Context</name>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed, thanks

String configPath = System.getProperty(PAYARA_BASEDIR_PROPERTY_NAME);
logger.log(Level.INFO, "Basedir value:"+configPath);
if (configPath != null) {
File file = new File(configPath.concat(PAYARA_KEYSTORE_NAME));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PAYARA_KEYSTORE_NAME is hard-coded to /target/test-classes/keystore.jks, so this is by proxy hard-coded to System.getProperty("basedir")/target/test-classes/keystore.jks.

That sounds very specific and more like something that belongs in a test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should bind to the server's keystore.

That can likely be achieved by utilizing com.sun.enterprise.security.ssl.SSLUtils (looked up via Globals.get()). I have no idea what either of the methods return over there, but it should give everything except for the chosen alias.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I returned to the SSLUtils and look better. I said returned because that was my first approach but I changed to add unit testing with mockito because of some static issues I saw previously

protected SSLContext buildSSlContext(String alias) {
logger.log(Level.INFO, "Building the SSLContext for the alias");
String configPath = System.getProperty(PAYARA_BASEDIR_PROPERTY_NAME);
logger.log(Level.INFO, "Basedir value:"+configPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting

Suggested change
logger.log(Level.INFO, "Basedir value:"+configPath);
logger.log(Level.INFO, "Basedir value:" + configPath);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed, thanks

File file = new File(configPath.concat(PAYARA_KEYSTORE_NAME));
logger.log(Level.INFO, file.getPath());
try (InputStream is = new FileInputStream(file)) {
String password = System.getProperty(PAYARA_KEYSTORE_PASSWORD_PROPERTY_NAME);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No support for password alias?
Have a look at TranslatedConfigView and its usages around the codebase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after returning with the use of the SSLUtils this is not requerid now


public static final String PAYARA_BASEDIR_PROPERTY_NAME = "basedir";

public static final String PAYARA_KEYSTORE_NAME = "/target/test-classes/keystore.jks";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work on Windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after adding improvements with the use of the SSLUtils this constants were removed


@Override
public void onNewClient(Class<?> serviceInterface, RestClientBuilder restClientBuilder) {
logger.log(Level.INFO,"Evaluating state of the RestClientBuilder after calling build method");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this really be INFO?
Seems more like a FINE.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed, thanks


if (objectProperty != null && objectProperty instanceof String) {
String alias = (String) objectProperty;
logger.log(Level.INFO,"The alias is available from the RestClientBuilder configuration");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The alias"
What alias? Would be nice to log the name.
And again - should this be INFO? Does a user need to know this as a matter of course?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed, thanks

String alias = config.getValue(PAYARA_MP_CONFIG_CLIENT_CERTIFICATE_ALIAS,
String.class);
if (alias != null) {
logger.log(Level.INFO,"The alias is available from the MP Config");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed, thanks


public static final String PAYARA_MP_CONFIG_CLIENT_CERTIFICATE_ALIAS = "certificate.alias";

public static final String PAYARA_BASEDIR_PROPERTY_NAME = "basedir";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property seems odd to me - what's the purpose of it?
It only seems to get combined with PAYARA_KEYSTORE_NAME and so seems redundant.
basedir also sounds very "maven-y".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after returning to the use of the SSLUtils now this property was removed

public class PayaraConstants {
public static final String PAYARA_REST_CLIENT_CERTIFICATE_ALIAS = "fish.payara.rest.client.certificate.alias";

public static final String PAYARA_MP_CONFIG_CLIENT_CERTIFICATE_ALIAS = "certificate.alias";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we're using separate names for system properties vs. MP config properties?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From starting requirements was mentioned to use the following combination of properties:

  • for JAX-RS: fish.payara.jaxrs.client.certificate.alias
  • for MP Rest: fish.payara.rest.client.certificate.alias=mykey
  • for MP Config something like: com.mycompany.remoteServices.MyServiceClient/payara/certificate.alias=mykey
    In the case of the MP Config after doing test I added on the design wiki just to use the value: certificate.alias=mykey

Do you think this is good or do you prefer to homologate values for example use the same from the MP Rest?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have them different, but I think the MP Config property should at least be prepended with payara. like most of our other properties.

https://docs.payara.fish/community/docs/documentation/microprofile/config/README.html#_payara_specific_configuration_properties

@Pandrex247
Copy link
Member

Test failure in Jenkins doesn't seem related to this PR since it is happening on other PRs too.
Caused by: java.security.cert.CertificateException: No name matching localhost found

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@Pandrex247 Pandrex247 self-requested a review October 15, 2021 15:15
Copy link
Member

@Pandrex247 Pandrex247 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't had time to create a reproducer yet, but couple of comments.

restClientBuilder.sslContext(customSSLContext);
} else {
logger.log(Level.INFO,
String.format("Although the alias: %s is configured, none keystore available for it", alias));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Readability

Suggested change
String.format("Although the alias: %s is configured, none keystore available for it", alias));
String.format("Although the alias: %s is configured, it could not be found in an available keystore", alias));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed

restClientBuilder.sslContext(customSSLContext);
} else {
logger.log(Level.INFO,
String.format("Although the alias: %s is configured, none keystore available for it", alias));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Readability

Suggested change
String.format("Although the alias: %s is configured, none keystore available for it", alias));
String.format("Although the alias: %s is configured, it could not be found in an available keystore", alias));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed

public class PayaraConstants {
public static final String PAYARA_REST_CLIENT_CERTIFICATE_ALIAS = "fish.payara.rest.client.certificate.alias";

public static final String PAYARA_MP_CONFIG_CLIENT_CERTIFICATE_ALIAS = "certificate.alias";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have them different, but I think the MP Config property should at least be prepended with payara. like most of our other properties.

https://docs.payara.fish/community/docs/documentation/microprofile/config/README.html#_payara_specific_configuration_properties

}
}
} catch (NoSuchElementException e) {
logger.log(Level.SEVERE, String.format("The MP config property %s was not set",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be severe? By default it won't be set!

Copy link
Contributor Author

@breakponchito breakponchito Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this to fine because as you mention this is not the default and this is not a potential problem. This only inform that the property was not set when evaluating the MP config

@breakponchito
Copy link
Contributor Author

Jenkins test

Object objectProperty = restClientBuilder.getConfiguration()
.getProperty(PAYARA_REST_CLIENT_CERTIFICATE_ALIAS);

if (objectProperty != null && objectProperty instanceof String) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instanceof implies null check

Suggested change
if (objectProperty != null && objectProperty instanceof String) {
if (objectProperty instanceof String) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already fixed

* This class is a custom implementation of X509KeyManager to set the custom certificate based on the
* alias property
*/
private class SingleCertificateKeyManager implements X509KeyManager {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I updated as static, thanks

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

2 similar comments
@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito
Copy link
Contributor Author

Jenkins test

@breakponchito breakponchito merged commit 3c53e8e into payara:master Oct 20, 2021
JamesHillyard pushed a commit to JamesHillyard/Payara that referenced this pull request Oct 28, 2021
…rtificate-alias-for-jaxrs-and-micro

FISH-230: specify certificate alias for MP rest client and MP config
@breakponchito breakponchito deleted the FISH-230-specify-certificate-alias-for-jaxrs-and-micro branch November 25, 2021 21:58
aubi pushed a commit to aubi/Payara that referenced this pull request Jan 3, 2022
…rtificate-alias-for-jaxrs-and-micro

FISH-230: specify certificate alias for MP rest client and MP config
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants