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

[#2825] Extend credentials management service to support auth-id template #2985

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

kaniyan
Copy link
Contributor

@kaniyan kaniyan commented Nov 30, 2021

  • Add issuer-DN to credentials management specification.

  • Extend credentials management service implementations to generate
    the auth-id by applying the auth-id-template to the given subject DN.

@kaniyan kaniyan requested a review from ctron as a code owner November 30, 2021 13:26
@kaniyan kaniyan added this to the 1.11.0 milestone Nov 30, 2021
@kaniyan kaniyan force-pushed the PR/#2825_part_2_authId_template branch from 2c9c5e8 to c2c01be Compare November 30, 2021 15:24
…auth-id template

* Add issuer-DN to credentials management specification.
* Extend credentials management service implementations
  to populate the new field generated-auth-id by applying
  the auth-id-template to the given subject DN.
* During find credentials by type and auth-id operation,
  the generated-auth-id is looked for any matching value.
  If there is no value, then the auth-id field is used.

Signed-off-by: Kartheeswaran Kalidass <[email protected]>
@kaniyan kaniyan force-pushed the PR/#2825_part_2_authId_template branch from c2c01be to a9af944 Compare December 3, 2021 10:26
@kaniyan
Copy link
Contributor Author

kaniyan commented Dec 3, 2021

@sophokles73 As we discussed, I added a new field generated-auth-id now to support the auth id template feature in JDBC and MongoDB registries. Also the get credentials operation has been extended to support this feature. I have pushed a consolidated commit for it.

Comment on lines 200 to 203
.map(c -> c.getString(RegistryManagementConstants.FIELD_TYPE))
.filter(RegistryManagementConstants.SECRETS_TYPE_X509_CERT::equals)
.map(ok -> credential.getString(RegistryManagementConstants.FIELD_GENERATED_AUTH_ID))
.ifPresent(id -> credential.put(RegistryManagementConstants.FIELD_AUTH_ID, id));
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is the Credentials service, I would assume that all these constants should be defined in CredentialsConstants, right?

@kaniyan kaniyan force-pushed the PR/#2825_part_2_authId_template branch from 973bd2b to 142b98a Compare December 6, 2021 18:49
* @param generatedAuthId the authentication identifier generated by applying the <em>auth-id-template</em>
* from the tenant's trust anchor to the client certificate's subject DN.
* @param secrets The credential's secret(s).
* @throws NullPointerException if any of the parameters are {@code null}.
Copy link
Contributor

Choose a reason for hiding this comment

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

the code seems to suggest that issuer DN and generatedAuthId can actually be null

* @throws NullPointerException if any of the parameters are {@code null}.
* @throws IllegalArgumentException if the given string is not a valid X.500 distinguished name or if
* secrets is empty.
* @throws NullPointerException if subject DN and secrets are {@code null}.
Copy link
Contributor

Choose a reason for hiding this comment

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

subject DN or secrets are null?

* @param secrets The credential's secret(s).
* @throws NullPointerException if certificate bytes and any of distinguished name and secrets are {@code null}.
* @throws NullPointerException if certificate bytes, subject DN and secrets are {@code null}.
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO the original wording was correct

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The distinguished name in the old wording is ambiguous as both issuer-dn and subject-dn are distinguished names.
How about if certificate bytes and any of subject DN and secrets are {@code null}?

Copy link
Contributor

Choose a reason for hiding this comment

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

it is not about distinguished name vs subject DN. it is about the expression built from the three parameters.

if certificate bytes and any of distinguished name and secrets are {@code null}

is true if either certificate bytes AND distinguished name are null, OR if certificate bytes AND secrets are null

but

if certificate bytes, subject DN and secrets are {@code null}.

is only true if all three parameters are null, or am I mistaken?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if certificate bytes, subject DN and secrets are {@code null}.

We agree on the same. The above one is not correct.

In my previous comment, I proposed the below one. I just replaced distinguished name with subject DN in the original description as we now have two distinguished names in the list of paramteres(final String subjectDN, final String issuerDN).

if certificate bytes and any of subject DN and secrets are {@code null}

Another suggestions is as below:

if certificate bytes and either subject DN or secrets are {@code null}

Or am I missing something?

final var credentialsArraySpec = document.getJsonObject(CredentialsDto.FIELD_CREDENTIALS, new JsonObject());
final var elementMatchSpec = credentialsArraySpec.getJsonObject(MONGODB_OPERATOR_ELEM_MATCH, new JsonObject());

elementMatchSpec.put(MONGODB_OPERATOR_OR, new JsonArray(List.of(
Copy link
Contributor

Choose a reason for hiding this comment

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

no need to create a List instance here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think a List is needed there as there are two JsonObjects to be added to the JsonArray. If we like to avoid using List, then it can be rewritten as below. One way of populating JsonArray is to pass a list to the constructor and another is to invoke add methods.

elementMatchSpec.put(MONGODB_OPERATOR_OR, new JsonArray().add(new JsonObject()).add(new JsonObject())

* The name of the field that contains the generated authentication identifier
* by applying the template to the subject DN.
*/
public static final String FIELD_GENERATED_AUTH_ID = "generated-auth-id";
Copy link
Contributor

Choose a reason for hiding this comment

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

do we still need this constant now that we do not expose the generated ID field anymore?

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 it is still being used in CredentialsServiceImpl.

Comment on lines 275 to 295
public final X509CertificateCredential applyAuthIdTemplate(final Tenant tenant) {
Objects.requireNonNull(tenant, "tenant information must not be null");

final String generatedAuthId = Optional.ofNullable(issuerDN)
.flatMap(tenant::getAuthIdTemplate)
.map(IdentityTemplate::new)
.map(t -> t.apply(getAuthId()))
.orElse(null);
final X509CertificateCredential credential = new X509CertificateCredential(getAuthId(),
generatedAuthId, secrets) {

@Override
@JsonGetter(value = RegistryManagementConstants.FIELD_GENERATED_AUTH_ID)
protected String getGeneratedAuthId() {
return super.getGeneratedAuthId();
}
};

copyCommonAttributesTo(credential);
return credential;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess that this works but, pardon my French, it looks like a hack. Wouldn't it be easier to understand and also much cleaner from a design perspective to introduce two subclasses instead, one for handling credentials with a generated ID and the other for a non-generated ID?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed that anonymous class approach is employed in several places in Hono. I chose that approach than my initial one. Good that I still have a backup of X509CertificateCredentialWithGeneratedAuthId ;-)

@kaniyan kaniyan force-pushed the PR/#2825_part_2_authId_template branch from 6e5e0b7 to 88c61ce Compare December 8, 2021 08:23
Signed-off-by: Kartheeswaran Kalidass <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants