Skip to content

Conversation

@acoburn
Copy link
Collaborator

@acoburn acoburn commented May 17, 2023

This makes use of the new ClientCache<K, V> mechanism, applying it to session credential objects.

This required inverting one section of the ReactiveAuthorization class. Before, the Authenticator::authenticate method accepted a Session parameter. Now, the Session::authenticate method accepts an Authenticator parameter:

return session.authenticate(auth, request, algorithms);

The previously used method is now deprecated.

This also changes the way the OpenIdSession::fromCache works. Previously, any fromCache requests returned an OpenId credential, which incorrectly bypasses reactive authorization. In this case, the is still only a single credential, but the internal cache keeps track of which URIs have performed reactive authorization and (provided that the credential is still valid), that ID Token credential will be provided.

@acoburn acoburn requested a review from a team as a code owner May 17, 2023 19:16
@acoburn acoburn force-pushed the JCL-279-session-cache-support branch from cb1e822 to b9a6fb6 Compare May 17, 2023 20:50
Comment on lines -70 to +80
!BEARER.equalsIgnoreCase(challenge.getScheme())) {
!schemes.contains(challenge.getScheme())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes the test case-sensitive, is it a problem?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, it's not case sensitive:

private final Set<String> schemes = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);

public Optional<Credential> fromCache(final Request request) {
// TODO add cache
final Credential cachedToken = tokenCache.get(request.uri());
if (cachedToken != null && cachedToken.getExpiration().isAfter(Instant.now())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If the token is cached, but expired, should it be removed from cache?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I considered this, but I was concerned that there would be a race condition:

If multiple threads are reading/updating the cache, one thread could have fetched the token from the cache (line 168) and before line 169 another thread could have updated the cache. So if the first thread then invalidates the cache, it would have done so unnecessarily, as it would have already been updated by another thread.

.withRequestBody(matching("Test String 1"))
.withHeader(CONTENT_TYPE, containing(TEXT_PLAIN))
.withHeader("Authorization", containing("Bearer token-67890"))
.withHeader("Authorization", containing("Bearer eyJ"))
Copy link
Contributor

Choose a reason for hiding this comment

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

For my own understanding, why was this required?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This allows us to vary the mock server response based on the presence of an auth token.

// Support case-insensitive lookups
final Set<String> schemeNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
schemeNames.add("Bearer");
schemeNames.add("DPoP");
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth using constants from OpenIdAuthenticationProvider instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Possibly -- I've generally been moving away from storing string constants in a single file and using them elsewhere. It makes no difference to the JVM, since there will only ever be a single instance of the string in memory.

final Optional<URI> principal = session.getPrincipal();
assertEquals(Optional.of(URI.create(WEBID)), principal);
assertTrue(session.fromCache(null).isPresent());
assertFalse(session.fromCache(null).isPresent());
Copy link
Contributor

Choose a reason for hiding this comment

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

Duplicates assertion from 3 lines above

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In the past, the cache would be populated at this point (which was incorrect). This assertion tests that the cache is still not populated.

@acoburn acoburn enabled auto-merge (squash) May 22, 2023 12:28
@acoburn acoburn merged commit ae5aa15 into main May 22, 2023
@acoburn acoburn deleted the JCL-279-session-cache-support branch May 22, 2023 12:53
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