From 8f38dd8ecbea385011a86ba1269757d29535bc63 Mon Sep 17 00:00:00 2001
From: Aiosa <469130@mail.muni.cz>
Date: Fri, 11 Oct 2024 09:58:20 +0200
Subject: [PATCH] chore: replace deprecated JwtHelper (does not support all
tokens) with nimbus jose JWT library, which is recommended even at jwt.io
---
pom.xml | 5 +++
.../OAuth2TokenAuthenticationProvider.java | 44 +++++++++----------
2 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/pom.xml b/pom.xml
index 8c7f248db5b..321dcd8357a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -353,6 +353,11 @@
${apache_httpclient.version}
test
+
+ com.nimbusds
+ nimbus-jose-jwt
+ 9.41.2
+
diff --git a/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenAuthenticationProvider.java b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenAuthenticationProvider.java
index d8dfafa7b66..f07fea44be5 100644
--- a/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenAuthenticationProvider.java
+++ b/src/main/java/org/cbioportal/security/token/oauth2/OAuth2TokenAuthenticationProvider.java
@@ -28,10 +28,16 @@
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
-*/
+ */
package org.cbioportal.security.token.oauth2;
+import java.util.Map;
+import java.util.Collection;
+import java.io.IOException;
+
+import com.nimbusds.jwt.JWTParser;
+import com.nimbusds.jwt.JWT;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.cbioportal.security.util.ClaimRoleExtractorUtil;
@@ -42,11 +48,9 @@
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.jwt.Jwt;
-import org.springframework.security.jwt.JwtHelper;
-import java.io.IOException;
-import java.util.Collection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class OAuth2TokenAuthenticationProvider implements AuthenticationProvider {
@@ -55,8 +59,10 @@ public class OAuth2TokenAuthenticationProvider implements AuthenticationProvider
private final OAuth2TokenRefreshRestTemplate tokenRefreshRestTemplate;
+ private static final Logger LOG = LoggerFactory.getLogger(OAuth2TokenAuthenticationProvider.class);
+
public OAuth2TokenAuthenticationProvider(OAuth2TokenRefreshRestTemplate tokenRefreshRestTemplate) {
- this.tokenRefreshRestTemplate = tokenRefreshRestTemplate;
+ this.tokenRefreshRestTemplate = tokenRefreshRestTemplate;
}
@Override
public boolean supports(Class> authentication) {
@@ -76,39 +82,31 @@ public Authentication authenticate(Authentication authentication) throws Authent
Collection authorities = extractAuthorities(accessToken);
String username = getUsername(accessToken);
-
return new OAuth2BearerAuthenticationToken(username, authorities);
}
// Read roles/authorities from JWT token.
private Collection extractAuthorities(final String token) throws BadCredentialsException {
try {
- final Jwt tokenDecoded = JwtHelper.decode(token);
- final String claims = tokenDecoded.getClaims();
+ final JWT tokenDecoded = JWTParser.parse(token);
+ final Map claims = tokenDecoded.getJWTClaimsSet().toJSONObject();
return GrantedAuthorityUtil.generateGrantedAuthoritiesFromRoles(ClaimRoleExtractorUtil.extractClientRoles(claims, jwtRolesPath));
} catch (Exception e) {
- throw new BadCredentialsException("Authorities could not be extracted from access token.");
+ throw new BadCredentialsException("Authorities could not be extracted from access token: " + e.getMessage());
}
}
private String getUsername(final String token) {
- final Jwt tokenDecoded = JwtHelper.decode(token);
-
- final String claims = tokenDecoded.getClaims();
- JsonNode claimsMap;
try {
- claimsMap = new ObjectMapper().readTree(claims);
- } catch (IOException e) {
- throw new BadCredentialsException("User name could not be found in access token.");
- }
-
- if (! claimsMap.has("sub")) {
- throw new BadCredentialsException("User name could not be found in access token.");
+ final JWT tokenDecoded = JWTParser.parse(token);
+ final Object sub = tokenDecoded.getJWTClaimsSet().getClaim("sub");
+ return (sub instanceof String) ? (String) sub : null;
+ } catch (Exception e) {
+ LOG.warn("Failed to parse token: authentiaction failed!", e);
+ return null;
}
-
- return claimsMap.get("sub").asText();
}
}