From fce732420cffc2530fe8804fc3babc18a9519c72 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:02:31 +0000 Subject: [PATCH 1/3] Initial plan From af9f3ed447fdb18e7fe191cf9db1e87835b9f83e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:05:25 +0000 Subject: [PATCH 2/3] Fix race condition using computeIfAbsent for atomic JwtDecoder creation Co-authored-by: buckett <5921+buckett@users.noreply.github.com> --- .../OidcLaunchFlowAuthenticationProvider.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java b/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java index 7964850..556ecf0 100644 --- a/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java +++ b/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java @@ -173,17 +173,14 @@ private JwtDecoder getJwtDecoder(ClientRegistration clientRegistration) { ); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); } - JwtDecoder jwtDecoder = this.jwtDecoders.get(jwkSetUri); - if (jwtDecoder == null) { - // TODO This should look at the Cache-Control header so to expire old jwtDecoders. - // Canvas looks to rotate it's keys monthly. - NimbusJwtDecoder.JwkSetUriJwtDecoderBuilder decoderBuilder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).jwsAlgorithm(SignatureAlgorithm.from(JwsAlgorithms.RS256)); + // TODO This should look at the Cache-Control header so to expire old jwtDecoders. + // Canvas looks to rotate it's keys monthly. + return this.jwtDecoders.computeIfAbsent(jwkSetUri, uri -> { + NimbusJwtDecoder.JwkSetUriJwtDecoderBuilder decoderBuilder = NimbusJwtDecoder.withJwkSetUri(uri).jwsAlgorithm(SignatureAlgorithm.from(JwsAlgorithms.RS256)); if (restOperations != null) { decoderBuilder.restOperations(restOperations); } - jwtDecoder = decoderBuilder.build(); - this.jwtDecoders.put(jwkSetUri, jwtDecoder); - } - return jwtDecoder; + return decoderBuilder.build(); + }); } } From a094915e0377365beba2ccc71dd8d8d539ba00a3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:06:03 +0000 Subject: [PATCH 3/3] Fix grammar in TODO comment (it's -> its) Co-authored-by: buckett <5921+buckett@users.noreply.github.com> --- .../authentication/OidcLaunchFlowAuthenticationProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java b/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java index 556ecf0..c8b5923 100644 --- a/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java +++ b/src/main/java/uk/ac/ox/ctl/lti13/security/oauth2/client/lti/authentication/OidcLaunchFlowAuthenticationProvider.java @@ -174,7 +174,7 @@ private JwtDecoder getJwtDecoder(ClientRegistration clientRegistration) { throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); } // TODO This should look at the Cache-Control header so to expire old jwtDecoders. - // Canvas looks to rotate it's keys monthly. + // Canvas looks to rotate its keys monthly. return this.jwtDecoders.computeIfAbsent(jwkSetUri, uri -> { NimbusJwtDecoder.JwkSetUriJwtDecoderBuilder decoderBuilder = NimbusJwtDecoder.withJwkSetUri(uri).jwsAlgorithm(SignatureAlgorithm.from(JwsAlgorithms.RS256)); if (restOperations != null) {