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.portal.PortalContext; 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 { // set the root scope ScopeProvider.instance.set("/" + PortalContext.getConfiguration().getInfrastructureName()); 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); }finally{ ScopeProvider.instance.reset(); } return res; } }