diff --git a/pom.xml b/pom.xml index eba528d..1a6b0c4 100644 --- a/pom.xml +++ b/pom.xml @@ -116,12 +116,6 @@ jersey-bean-validation ${version.jersey} - - - org.gcube.core - common-smartgears - provided - org.gcube.resources.discovery ic-client diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ApplicationException.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ApplicationException.java index 93c383b..0e5501d 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ApplicationException.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ApplicationException.java @@ -5,6 +5,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; +import org.slf4j.LoggerFactory; + @Provider /** * Exception thrown when @Valid fail @@ -12,7 +14,10 @@ import javax.ws.rs.ext.Provider; */ public class ApplicationException implements ExceptionMapper { + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ApplicationException.class); + public Response toResponse(Exception e) { + logger.warn("ApplicationException invoked"); return Response .status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) .type(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ValidationException.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ValidationException.java index e4e0e59..64ae890 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ValidationException.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/ex/ValidationException.java @@ -7,12 +7,15 @@ import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; +import org.slf4j.LoggerFactory; + @Provider /** * Exception thrown on fail * @author Costantino Perciante at ISTI-CNR */ public class ValidationException implements ExceptionMapper { + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ValidationException.class); @Override public Response toResponse(javax.validation.ValidationException e) { @@ -20,6 +23,7 @@ public class ValidationException implements ExceptionMapper cv : ((ConstraintViolationException) e).getConstraintViolations()) { strBuilder.append(cv.getPropertyPath().toString() + " " + cv.getMessage()); } + logger.warn("ValidationException invoked, returning " + strBuilder.toString()); return Response .status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) .type(MediaType.APPLICATION_JSON) diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/filters/RequestsAuthFilter.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/filters/RequestsAuthFilter.java new file mode 100644 index 0000000..d6a1fc7 --- /dev/null +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/filters/RequestsAuthFilter.java @@ -0,0 +1,95 @@ +package org.gcube.data_catalogue.grsf_publish_ws.filters; + +import static org.gcube.common.authorization.client.Constants.authorizationService; + +import java.io.IOException; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; + +import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.utils.Caller; +import org.gcube.common.scope.api.ScopeProvider; +import org.slf4j.LoggerFactory; + + +/** + * Requests filter: is invoked before any request reaches a service method + * @author Costantino Perciante at ISTI-CNR + */ +@Provider +public class RequestsAuthFilter implements ContainerRequestFilter{ + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(RequestsAuthFilter.class); + private static final String AUTH_TOKEN = "gcube-token"; + @Override + public void filter(ContainerRequestContext requestContext) + throws IOException { + + logger.info("Intercepted request, checking if it contains authorization token"); + + // check if the request contains gcube-token + String tokenInHeader = null, tokenAsQueryParameter = null; + MultivaluedMap headers = requestContext.getHeaders(); + if( headers != null && headers.containsKey(AUTH_TOKEN)) + tokenInHeader = headers.get(AUTH_TOKEN).get(0); + + MultivaluedMap queryParameters = requestContext.getUriInfo().getQueryParameters(); + if(queryParameters != null && queryParameters.containsKey(AUTH_TOKEN)) + tokenAsQueryParameter = queryParameters.get(AUTH_TOKEN).get(0); + + if(tokenInHeader != null){ + logger.info("Token in " + tokenInHeader.substring(0, 5) + "********************"); + AuthorizationEntry ae = validateToken(tokenInHeader); + if(ae != null){ + logger.debug("Setting scope " + ae.getContext()); + AuthorizationProvider.instance.set(new Caller(ae.getClientInfo(), ae.getQualifier())); + ScopeProvider.instance.set(ae.getContext()); + logger.info("Authorization entry set in thread local"); + return; + }else + requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Invalid or missing gcube-token").build()); + }else if(tokenAsQueryParameter != null){ + logger.info("Token is " + tokenAsQueryParameter.substring(0, 5) + "********************"); + AuthorizationEntry ae = validateToken(tokenAsQueryParameter); + if(ae != null){ + logger.debug("Setting scope " + ae.getContext()); + AuthorizationProvider.instance.set(new Caller(ae.getClientInfo(), ae.getQualifier())); + ScopeProvider.instance.set(ae.getContext()); + logger.info("Authorization entry set in thread local"); + return; + }else + requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Invalid or missing gcube-token").build()); + + } + else + requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Invalid or missing gcube-token").build()); + + } + + /** + * Validate token. + * @param token + * @return null if validation fails + */ + private static AuthorizationEntry validateToken(String token){ + AuthorizationEntry res = null; + try { + + logger.debug("Validating token " + token); + res = authorizationService().get(token); + logger.debug("Token seems valid for scope " + res.getContext() + " and user " + res.getClientInfo().getId()); + + } catch (Exception e) { + logger.error("The token is not valid. This request will be rejected!!! (" + token + ")", e); + } + + return res; + } + + +} diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 85f941e..260256a 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -10,7 +10,7 @@ org.glassfish.jersey.servlet.ServletContainer jersey.config.server.provider.packages - org.gcube.data_catalogue.grsf_publish_ws.services + org.gcube.data_catalogue.grsf_publish_ws jersey.config.beanValidation.enableOutputValidationErrorEntity.server