Intregrated authorization-utils in place of ad-hoc code
This commit is contained in:
parent
9239e13120
commit
29ac4def10
|
@ -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
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -11,7 +11,7 @@
|
|||
|
||||
<groupId>org.gcube.core</groupId>
|
||||
<artifactId>common-smartgears</artifactId>
|
||||
<version>3.1.2-SNAPSHOT</version>
|
||||
<version>3.2.0-SNAPSHOT</version>
|
||||
<name>SmartGears</name>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@ -70,7 +70,7 @@
|
|||
<dependency>
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>authorization-utils</artifactId>
|
||||
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
|
||||
<version>[2.0.0-SNAPSHOT,3.0.0-SNAPSHOT)</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String> MINIMAL_ROLES = Arrays.asList("Member");
|
||||
|
||||
@JsonProperty("aud")
|
||||
private String context;
|
||||
|
||||
@JsonProperty("resource_access")
|
||||
private Map<String, Roles> 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<String> 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<String> roles = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue