From 29ac4def10a481c672af01aae0c188efaeed4034 Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Fri, 25 Feb 2022 15:07:09 +0100 Subject: [PATCH] Intregrated authorization-utils in place of ad-hoc code --- CHANGELOG.md | 5 + pom.xml | 4 +- .../request/RequestContextRetriever.java | 129 +++++------------- .../org/gcube/smartgears/utils/GcubeJwt.java | 79 ----------- 4 files changed, 42 insertions(+), 175 deletions(-) delete mode 100644 src/main/java/org/gcube/smartgears/utils/GcubeJwt.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a7a06f..ebfd6dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm # Changelog for Common Smartgears +## [v3.2.0-SNAPSHOT] + +- Added SecretManager thread local from authorization-utils [#22871] + + ## [v3.1.2-SNAPSHOT] - 2022-01-19 - enabled policy check on smartgears diff --git a/pom.xml b/pom.xml index 24be6f2..65aac6f 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.gcube.core common-smartgears - 3.1.2-SNAPSHOT + 3.2.0-SNAPSHOT SmartGears @@ -70,7 +70,7 @@ org.gcube.common authorization-utils - [1.0.0,2.0.0-SNAPSHOT) + [2.0.0-SNAPSHOT,3.0.0-SNAPSHOT) diff --git a/src/main/java/org/gcube/smartgears/handlers/application/request/RequestContextRetriever.java b/src/main/java/org/gcube/smartgears/handlers/application/request/RequestContextRetriever.java index c0de5a5..2e57d75 100644 --- a/src/main/java/org/gcube/smartgears/handlers/application/request/RequestContextRetriever.java +++ b/src/main/java/org/gcube/smartgears/handlers/application/request/RequestContextRetriever.java @@ -1,31 +1,21 @@ package org.gcube.smartgears.handlers.application.request; -import static org.gcube.common.authorization.client.Constants.authorizationService; import static org.gcube.smartgears.Constants.scope_header; import static org.gcube.smartgears.Constants.token_header; import static org.gcube.smartgears.handlers.application.request.RequestError.internal_server_error; -import static org.gcube.smartgears.handlers.application.request.RequestError.invalid_request_error; import java.util.Base64; import javax.xml.bind.annotation.XmlRootElement; -import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; -import org.gcube.common.authorization.client.exceptions.ObjectNotFound; -import org.gcube.common.authorization.library.AuthorizationEntry; -import org.gcube.common.authorization.library.provider.AccessTokenProvider; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; -import org.gcube.common.authorization.library.provider.SecurityTokenProvider; -import org.gcube.common.authorization.library.provider.UserInfo; -import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.authorization.utils.manager.SecretManager; +import org.gcube.common.authorization.utils.secret.GCubeSecret; +import org.gcube.common.authorization.utils.secret.JWTSecret; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.common.scope.impl.ScopeBean; import org.gcube.smartgears.Constants; import org.gcube.smartgears.handlers.application.RequestEvent; import org.gcube.smartgears.handlers.application.RequestHandler; import org.gcube.smartgears.handlers.application.ResponseEvent; -import org.gcube.smartgears.utils.GcubeJwt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,8 +41,8 @@ public class RequestContextRetriever extends RequestHandler { String authHeader = call.request().getHeader(Constants.authorization_header); log.trace("authorization header is {}",authHeader); - log.trace("token header is {}",token); - log.trace("scope header is {}",scope); + log.trace("token header is {}", token); + log.trace("scope header is {}", scope); String retrievedUser = null; String accessToken = null; @@ -68,92 +58,43 @@ public class RequestContextRetriever extends RequestHandler { } } - //Gives priority to the umaToken - if (accessToken!=null) { - this.retreiveAndSetInfoUmaToken(accessToken, token, call); - } else if (token!=null) - this.retreiveAndSetInfoGcubeToken(token, retrievedUser, call); - else if (scope!=null) - ScopeProvider.instance.set(scope); + SecretManager secretManager = SecretManager.instance.get(); + + if (accessToken!=null) { + JWTSecret jwtSecret = new JWTSecret(accessToken); + secretManager.addSecret(jwtSecret); + } + + if (token!=null) { + GCubeSecret gCubeSecret = new GCubeSecret(token); + secretManager.addSecret(gCubeSecret); + try { + if (retrievedUser != null && !gCubeSecret.getClientInfo().getId().equals(retrievedUser)) { + internal_server_error.fire("user and token owner are not the same"); + } + }catch (Exception e) { + internal_server_error.fire(e.getMessage()); + } + } + + if(accessToken==null && token==null) { + if(scope!=null) { + ScopeProvider.instance.set(scope); + } + }else { + try { + secretManager.set(); + } catch (Exception e) { + internal_server_error.fire(e.getMessage()); + } + } - SecretManager.instance.get(); } @Override public void handleResponse(ResponseEvent e) { - // This should be enough but maintaining also the old resets - SecretManager.instance.get().reset(); - - SecurityTokenProvider.instance.reset(); - AuthorizationProvider.instance.reset(); - AccessTokenProvider.instance.reset(); - ScopeProvider.instance.reset(); log.debug("resetting all the Thread local for this call."); + SecretManager.instance.get().reset(); } - - private void retreiveAndSetInfoGcubeToken(String token, String retrievedUser, RequestEvent call){ - log.trace("retrieving context using token {} ", token); - AuthorizationEntry authEntry = null; - try{ - authEntry = authorizationService().get(token); - if (retrievedUser != null && !authEntry.getClientInfo().getId().equals(retrievedUser)) - throw new Exception("user and token owner are not the same"); - }catch(ObjectNotFound onf){ - log.warn("rejecting call to {}, invalid token {}",call.context().name(),token); - invalid_request_error.fire(call.context().name()+" invalid token : "+token); - }catch(Exception e){ - log.error("error contacting authorization service",e); - internal_server_error.fire("error contacting authorization service"); - } - - AuthorizationProvider.instance.set(new Caller(authEntry.getClientInfo(), authEntry.getQualifier())); - SecurityTokenProvider.instance.set(token); - ScopeProvider.instance.set(authEntry.getContext()); - log.info("retrieved request authorization info {} in scope {} ", AuthorizationProvider.instance.get(), authEntry.getContext()); - } - - private void retreiveAndSetInfoUmaToken(String accessToken, String gcubeToken, RequestEvent call){ - log.debug("using UMA token for authorization"); - log.trace("retrieving context using uma token {} ", accessToken); - - AccessTokenProvider.instance.set(accessToken); - SecurityTokenProvider.instance.set(gcubeToken); - parseAccessTokenAndSet(accessToken); - log.info("retrieved request authorization info {} in scope {} ", AuthorizationProvider.instance.get(), ScopeProvider.instance.get()); - } - - private void parseAccessTokenAndSet(String umaToken) { - - String realUmaTokenEncoded = umaToken.split("\\.")[1]; - - String realUmaToken = new String(Base64.getDecoder().decode(realUmaTokenEncoded.getBytes())); - - ObjectMapper mapper = new ObjectMapper(); - - - GcubeJwt jwt = null; - try { - jwt = mapper.readValue(realUmaToken, GcubeJwt.class); - }catch(Exception e){ - log.error("error decoding uma token",e); - internal_server_error.fire("error parsing access token"); - } - - - ScopeBean scopeBean = null; - try { - scopeBean = new ScopeBean(jwt.getContext()); - }catch(Exception e){ - log.error("error decoding uma token",e); - internal_server_error.fire("invalid context in access token"); - } - - AuthorizationProvider.instance.set(new Caller(new UserInfo(jwt.getUsername(), jwt.getRoles(), jwt.getEmail(), jwt.getFirstName(), jwt.getLastName()), "token")); - - ScopeProvider.instance.set(scopeBean.toString()); - - } - - } diff --git a/src/main/java/org/gcube/smartgears/utils/GcubeJwt.java b/src/main/java/org/gcube/smartgears/utils/GcubeJwt.java deleted file mode 100644 index b86540c..0000000 --- a/src/main/java/org/gcube/smartgears/utils/GcubeJwt.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.gcube.smartgears.utils; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.gcube.com.fasterxml.jackson.annotation.JsonProperty; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class GcubeJwt { - - protected final static List MINIMAL_ROLES = Arrays.asList("Member"); - - @JsonProperty("aud") - private String context; - - @JsonProperty("resource_access") - private Map contextAccess = new HashMap<>(); - - @JsonProperty("preferred_username") - private String username; - - @JsonProperty("given_name") - private String firstName; - - @JsonProperty("family_name") - private String lastName; - - @JsonProperty("email") - private String email; - - public List getRoles(){ - return contextAccess.get(this.context) == null ? MINIMAL_ROLES : contextAccess.get(this.context).roles; - } - - public String getContext() { - try { - return URLDecoder.decode(context, StandardCharsets.UTF_8.toString()); - }catch (UnsupportedEncodingException e) { - return context; - } - } - - public String getUsername() { - return username; - } - - public String getFirstName() { - return firstName; - } - - public String getLastName() { - return lastName; - } - - public String getEmail() { - return email; - } - - @Override - public String toString() { - return "GcubeJwt [context=" + getContext() + ", roles=" + getRoles() + ", username=" + username - + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]"; - } - - public static class Roles { - - @JsonProperty("roles") - List roles = new ArrayList<>(); - - } - -}