2017-07-28 12:09:32 +02:00
|
|
|
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;
|
|
|
|
|
2020-11-18 18:50:49 +01:00
|
|
|
import java.util.Base64;
|
|
|
|
|
2017-07-28 12:09:32 +02:00
|
|
|
import javax.xml.bind.annotation.XmlRootElement;
|
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
2017-07-28 12:09:32 +02:00
|
|
|
import org.gcube.common.authorization.client.exceptions.ObjectNotFound;
|
|
|
|
import org.gcube.common.authorization.library.AuthorizationEntry;
|
2021-05-24 16:31:46 +02:00
|
|
|
import org.gcube.common.authorization.library.provider.AccessTokenProvider;
|
2017-07-28 12:09:32 +02:00
|
|
|
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
|
|
|
|
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
2020-11-18 18:50:49 +01:00
|
|
|
import org.gcube.common.authorization.library.provider.UserInfo;
|
2017-07-28 12:09:32 +02:00
|
|
|
import org.gcube.common.authorization.library.utils.Caller;
|
|
|
|
import org.gcube.common.scope.api.ScopeProvider;
|
2020-11-18 18:50:49 +01:00
|
|
|
import org.gcube.common.scope.impl.ScopeBean;
|
2017-07-28 12:09:32 +02:00
|
|
|
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;
|
2021-05-24 16:31:46 +02:00
|
|
|
import org.gcube.smartgears.utils.GcubeJwt;
|
2017-07-28 12:09:32 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
@XmlRootElement(name = Constants.request_context_retriever)
|
|
|
|
public class RequestContextRetriever extends RequestHandler {
|
|
|
|
|
|
|
|
private static Logger log = LoggerFactory.getLogger(RequestContextRetriever.class);
|
2019-04-16 17:12:48 +02:00
|
|
|
|
|
|
|
private static final String BEARER_AUTH_PREFIX ="Bearer";
|
|
|
|
private static final String BASIC_AUTH_PREFIX ="Basic";
|
|
|
|
|
|
|
|
|
2017-07-28 12:09:32 +02:00
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return Constants.request_context_retriever;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handleRequest(RequestEvent call) {
|
|
|
|
String token = call.request().getParameter(token_header)==null? call.request().getHeader(token_header):call.request().getParameter(token_header);
|
|
|
|
String scope = call.request().getParameter(scope_header)==null? call.request().getHeader(scope_header):call.request().getParameter(scope_header);
|
2020-11-18 18:50:49 +01:00
|
|
|
|
|
|
|
String authHeader = call.request().getHeader(Constants.authorization_header);
|
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
log.trace("authorization header is {}",authHeader);
|
|
|
|
log.trace("token header is {}",token);
|
|
|
|
log.trace("scope header is {}",scope);
|
2020-11-18 18:50:49 +01:00
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
String retrievedUser = null;
|
|
|
|
String accessToken = null;
|
2020-11-18 18:50:49 +01:00
|
|
|
if (authHeader!=null && !authHeader.isEmpty()) {
|
|
|
|
if (authHeader.startsWith(BEARER_AUTH_PREFIX))
|
2021-05-24 16:31:46 +02:00
|
|
|
accessToken = authHeader.substring(BEARER_AUTH_PREFIX.length()).trim();
|
2020-11-18 18:50:49 +01:00
|
|
|
else if (token==null && authHeader.startsWith(BASIC_AUTH_PREFIX)) {
|
|
|
|
String basicAuthToken = authHeader.substring(BASIC_AUTH_PREFIX.length()).trim();
|
|
|
|
String decodedAuth = new String(Base64.getDecoder().decode(basicAuthToken.getBytes()));
|
2021-05-24 16:31:46 +02:00
|
|
|
String[] splitAuth = decodedAuth.split(":");
|
|
|
|
token = splitAuth[1];
|
|
|
|
retrievedUser = splitAuth[0];
|
2020-11-18 18:50:49 +01:00
|
|
|
}
|
2017-07-28 12:09:32 +02:00
|
|
|
}
|
2021-05-24 16:31:46 +02:00
|
|
|
|
|
|
|
//Gives priority to the umaToken
|
|
|
|
if (accessToken!=null) {
|
|
|
|
this.retreiveAndSetInfoUmaToken(accessToken, token, call);
|
2020-11-18 18:50:49 +01:00
|
|
|
} else if (token!=null)
|
2021-05-24 16:31:46 +02:00
|
|
|
this.retreiveAndSetInfoGcubeToken(token, retrievedUser, call);
|
2017-07-28 12:09:32 +02:00
|
|
|
else if (scope!=null)
|
|
|
|
ScopeProvider.instance.set(scope);
|
2021-05-24 16:31:46 +02:00
|
|
|
|
2017-07-28 12:09:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handleResponse(ResponseEvent e) {
|
|
|
|
SecurityTokenProvider.instance.reset();
|
|
|
|
AuthorizationProvider.instance.reset();
|
2021-05-24 16:31:46 +02:00
|
|
|
AccessTokenProvider.instance.reset();
|
2017-07-28 12:09:32 +02:00
|
|
|
ScopeProvider.instance.reset();
|
|
|
|
log.debug("resetting all the Thread local for this call.");
|
|
|
|
}
|
2019-04-16 17:12:48 +02:00
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
private void retreiveAndSetInfoGcubeToken(String token, String retrievedUser, RequestEvent call){
|
2020-11-18 18:50:49 +01:00
|
|
|
log.trace("retrieving context using token {} ", token);
|
2017-07-28 12:09:32 +02:00
|
|
|
AuthorizationEntry authEntry = null;
|
|
|
|
try{
|
|
|
|
authEntry = authorizationService().get(token);
|
2021-06-15 10:33:15 +02:00
|
|
|
if (retrievedUser != null && !authEntry.getClientInfo().getId().equals(retrievedUser))
|
2021-05-24 16:31:46 +02:00
|
|
|
throw new Exception("user and token owner are not the same");
|
2017-07-28 12:09:32 +02:00
|
|
|
}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");
|
|
|
|
}
|
2019-04-16 17:12:48 +02:00
|
|
|
|
2017-07-28 12:09:32 +02:00
|
|
|
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());
|
|
|
|
}
|
2020-11-18 18:50:49 +01:00
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
private void retreiveAndSetInfoUmaToken(String accessToken, String gcubeToken, RequestEvent call){
|
2020-11-18 18:50:49 +01:00
|
|
|
log.debug("using UMA token for authorization");
|
2021-05-24 16:31:46 +02:00
|
|
|
log.trace("retrieving context using uma token {} ", accessToken);
|
2020-11-18 18:50:49 +01:00
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
AccessTokenProvider.instance.set(accessToken);
|
2020-11-18 18:50:49 +01:00
|
|
|
SecurityTokenProvider.instance.set(gcubeToken);
|
2021-05-24 16:31:46 +02:00
|
|
|
parseAccessTokenAndSet(accessToken);
|
2020-11-18 18:50:49 +01:00
|
|
|
log.info("retrieved request authorization info {} in scope {} ", AuthorizationProvider.instance.get(), ScopeProvider.instance.get());
|
|
|
|
}
|
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
private void parseAccessTokenAndSet(String umaToken) {
|
2020-11-18 18:50:49 +01:00
|
|
|
|
|
|
|
String realUmaTokenEncoded = umaToken.split("\\.")[1];
|
|
|
|
|
|
|
|
String realUmaToken = new String(Base64.getDecoder().decode(realUmaTokenEncoded.getBytes()));
|
2021-05-24 16:31:46 +02:00
|
|
|
|
|
|
|
ObjectMapper mapper = new ObjectMapper();
|
2020-11-18 18:50:49 +01:00
|
|
|
|
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2020-11-18 18:50:49 +01:00
|
|
|
|
|
|
|
ScopeBean scopeBean = null;
|
|
|
|
try {
|
2021-05-24 16:31:46 +02:00
|
|
|
scopeBean = new ScopeBean(jwt.getContext());
|
2020-11-18 18:50:49 +01:00
|
|
|
}catch(Exception e){
|
|
|
|
log.error("error decoding uma token",e);
|
2021-05-24 16:31:46 +02:00
|
|
|
internal_server_error.fire("invalid context in access token");
|
2020-11-18 18:50:49 +01:00
|
|
|
}
|
|
|
|
|
2021-05-24 16:31:46 +02:00
|
|
|
AuthorizationProvider.instance.set(new Caller(new UserInfo(jwt.getUsername(), jwt.getRoles(), jwt.getEmail(), jwt.getFirstName(), jwt.getLastName()), "token"));
|
|
|
|
|
2020-11-18 18:50:49 +01:00
|
|
|
ScopeProvider.instance.set(scopeBean.toString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-07-28 12:09:32 +02:00
|
|
|
}
|