removed context retriver handler and merged with Request validator
This commit is contained in:
parent
f6e49975d0
commit
a285c20b38
|
@ -5,7 +5,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||||
|
|
||||||
## [v4.0.0-SNAPSHOT]
|
## [v4.0.0-SNAPSHOT]
|
||||||
|
|
||||||
|
- porting to keycloak
|
||||||
|
|
||||||
|
|
||||||
## [v3.2.0-SNAPSHOT]
|
## [v3.2.0-SNAPSHOT]
|
||||||
|
|
39
pom.xml
39
pom.xml
|
@ -20,7 +20,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.distribution</groupId>
|
<groupId>org.gcube.distribution</groupId>
|
||||||
<artifactId>gcube-bom</artifactId>
|
<artifactId>gcube-bom</artifactId>
|
||||||
<version>2.1.0-SNAPSHOT</version>
|
<version>3.0.0-SNAPSHOT</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
@ -56,29 +56,11 @@
|
||||||
<artifactId>gcube-jackson-core</artifactId>
|
<artifactId>gcube-jackson-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- END gCube Jackson -->
|
<!-- END gCube Jackson -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.common</groupId>
|
<groupId>org.gcube.common</groupId>
|
||||||
<artifactId>keycloak-client</artifactId>
|
<artifactId>common-security</artifactId>
|
||||||
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.gcube.common</groupId>
|
|
||||||
<artifactId>authorization-utils</artifactId>
|
|
||||||
<version>[2.0.0-SNAPSHOT,3.0.0-SNAPSHOT)</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.gcube.common</groupId>
|
|
||||||
<artifactId>authorization-client</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.gcube.common</groupId>
|
|
||||||
<artifactId>common-authorization</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.data.publishing</groupId>
|
<groupId>org.gcube.data.publishing</groupId>
|
||||||
<artifactId>document-store-lib</artifactId>
|
<artifactId>document-store-lib</artifactId>
|
||||||
|
@ -130,10 +112,23 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
<version>3.0.1</version>
|
<version>4.0.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/io.micrometer/micrometer-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.micrometer</groupId>
|
||||||
|
<artifactId>micrometer-core</artifactId>
|
||||||
|
<version>1.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.micrometer</groupId>
|
||||||
|
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||||
|
<version>1.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- ***************** test ******************* -->
|
<!-- ***************** test ******************* -->
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,14 @@ import org.gcube.smartgears.provider.ProviderFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.Metrics;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
|
||||||
|
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
|
||||||
|
import io.micrometer.prometheus.PrometheusConfig;
|
||||||
|
import io.micrometer.prometheus.PrometheusMeterRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bootstraps management of all deployed applications which require it.
|
* Bootstraps management of all deployed applications which require it.
|
||||||
*
|
*
|
||||||
|
@ -86,6 +94,17 @@ public class Bootstrap implements ServletContainerInitializer {
|
||||||
/* Get the ContainerContext. Look at DefaultProvider */
|
/* Get the ContainerContext. Look at DefaultProvider */
|
||||||
context = ProviderFactory.provider().containerContext();
|
context = ProviderFactory.provider().containerContext();
|
||||||
|
|
||||||
|
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
|
||||||
|
registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
|
||||||
|
new ClassLoaderMetrics().bindTo(registry);
|
||||||
|
new JvmMemoryMetrics().bindTo(registry);
|
||||||
|
//new JvmGcMetrics().bindTo(registry);
|
||||||
|
new ProcessorMetrics().bindTo(registry);
|
||||||
|
new JvmThreadMetrics().bindTo(registry);
|
||||||
|
|
||||||
|
Metrics.addRegistry(registry);
|
||||||
|
|
||||||
|
|
||||||
/* Validate the configuration retrieved by ContainerContext
|
/* Validate the configuration retrieved by ContainerContext
|
||||||
* using gcube facilities annotation based
|
* using gcube facilities annotation based
|
||||||
* ( i.e org.gcube.common.validator.annotations)
|
* ( i.e org.gcube.common.validator.annotations)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.gcube.smartgears.extensions.resource;
|
||||||
|
|
||||||
|
import static org.gcube.smartgears.Constants.plain_text;
|
||||||
|
import static org.gcube.smartgears.extensions.HttpExtension.Method.GET;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.gcube.smartgears.extensions.ApiResource;
|
||||||
|
import org.gcube.smartgears.extensions.ApiSignature;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.Metrics;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
|
||||||
|
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
|
||||||
|
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
|
||||||
|
import io.micrometer.prometheus.PrometheusConfig;
|
||||||
|
import io.micrometer.prometheus.PrometheusMeterRegistry;
|
||||||
|
|
||||||
|
public class MetricsResource extends ApiResource {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final String mapping = "/metrics";
|
||||||
|
|
||||||
|
private static final ApiSignature signature = handles(mapping).with(method(GET).produces(plain_text));
|
||||||
|
|
||||||
|
|
||||||
|
MetricsResource() {
|
||||||
|
super(signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
PrometheusMeterRegistry registry = (PrometheusMeterRegistry) Metrics.globalRegistry.getRegistries().stream().findFirst().get();
|
||||||
|
registry.scrape(resp.getWriter());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ public class RemoteResource extends HttpController {
|
||||||
public RemoteResource() {
|
public RemoteResource() {
|
||||||
super(remote_management, default_mapping);
|
super(remote_management, default_mapping);
|
||||||
addResources(new FrontPageResource(), new ConfigurationResource(), new ProfileResource(),
|
addResources(new FrontPageResource(), new ConfigurationResource(), new ProfileResource(),
|
||||||
new LifecycleResource());
|
new LifecycleResource(), new MetricsResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
package org.gcube.smartgears.handlers.application.request;
|
package org.gcube.smartgears.handlers.application.request;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
|
import org.gcube.accounting.datamodel.UsageRecord.OperationResult;
|
||||||
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
|
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
|
||||||
import org.gcube.accounting.persistence.AccountingPersistence;
|
import org.gcube.accounting.persistence.AccountingPersistence;
|
||||||
import org.gcube.accounting.persistence.AccountingPersistenceFactory;
|
import org.gcube.accounting.persistence.AccountingPersistenceFactory;
|
||||||
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
|
|
||||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
||||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
|
||||||
import org.gcube.common.scope.api.ScopeProvider;
|
import org.gcube.common.scope.api.ScopeProvider;
|
||||||
import org.gcube.smartgears.Constants;
|
import org.gcube.smartgears.Constants;
|
||||||
import org.gcube.smartgears.configuration.Mode;
|
import org.gcube.smartgears.configuration.Mode;
|
||||||
|
@ -20,23 +20,28 @@ import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.Metrics;
|
||||||
|
import io.micrometer.core.instrument.Timer;
|
||||||
|
import io.micrometer.core.instrument.Timer.Sample;
|
||||||
|
|
||||||
@XmlRootElement(name = Constants.request_accounting)
|
@XmlRootElement(name = Constants.request_accounting)
|
||||||
public class RequestAccounting extends RequestHandler {
|
public class RequestAccounting extends RequestHandler {
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(RequestAccounting.class);
|
private static Logger log = LoggerFactory.getLogger(RequestAccounting.class);
|
||||||
|
|
||||||
private static ThreadLocal<Long> startCallThreadLocal = new ThreadLocal<Long>();
|
private static ThreadLocal<Long> startCallThreadLocal = new ThreadLocal<Long>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return Constants.request_accounting;
|
return Constants.request_accounting;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(RequestEvent e) {
|
public void handleRequest(RequestEvent e) {
|
||||||
ApplicationContext context = e.context();
|
ApplicationContext context = e.context();
|
||||||
|
|
||||||
String calledMethod = e.request().getHeader(Constants.called_method_header);
|
String calledMethod = e.request().getHeader(Constants.called_method_header);
|
||||||
if (calledMethod==null){
|
if (calledMethod==null){
|
||||||
calledMethod = e.request().getRequestURI().substring(e.request().getContextPath().length());
|
calledMethod = e.request().getRequestURI().substring(e.request().getContextPath().length());
|
||||||
|
@ -45,45 +50,58 @@ public class RequestAccounting extends RequestHandler {
|
||||||
calledMethod= e.request().getMethod()+" "+calledMethod;
|
calledMethod= e.request().getMethod()+" "+calledMethod;
|
||||||
}
|
}
|
||||||
InnerMethodName.instance.set(calledMethod);
|
InnerMethodName.instance.set(calledMethod);
|
||||||
String caller = SecretManagerProvider.instance.get().getUser().getUsername();
|
String caller = "Unknown";
|
||||||
startCallThreadLocal.set(System.currentTimeMillis());
|
startCallThreadLocal.set(System.currentTimeMillis());
|
||||||
|
|
||||||
log.info("REQUEST START ON {}:{}({}) CALLED FROM {}@{} IN SCOPE {} ",
|
log.info("REQUEST START ON {}:{}({}) CALLED FROM {}@{} IN SCOPE {} ",
|
||||||
context.configuration().name(),context.configuration().serviceClass(), InnerMethodName.instance.get(),
|
context.configuration().name(),context.configuration().serviceClass(), InnerMethodName.instance.get(),
|
||||||
caller, e.request().getRemoteHost(), ScopeProvider.instance.get());
|
caller, e.request().getRemoteHost(), ScopeProvider.instance.get());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleResponse(ResponseEvent e) {
|
public void handleResponse(ResponseEvent e) {
|
||||||
ApplicationContext context = e.context();
|
ApplicationContext context = e.context();
|
||||||
|
|
||||||
boolean resetScope = false;
|
try {
|
||||||
if (ScopeProvider.instance.get()==null && SecurityTokenProvider.instance.get()==null){
|
boolean resetScope = false;
|
||||||
String infrastructure = e.context().container().configuration().infrastructure();
|
if (ScopeProvider.instance.get()==null && SecurityTokenProvider.instance.get()==null){
|
||||||
ScopeProvider.instance.set("/"+infrastructure);
|
String infrastructure = e.context().container().configuration().infrastructure();
|
||||||
resetScope = true;
|
ScopeProvider.instance.set("/"+infrastructure);
|
||||||
|
resetScope = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String caller = "Unknown";
|
||||||
|
String callerQualifier = "UNKNOWN";
|
||||||
|
//retieves caller Ip when there is a proxy
|
||||||
|
String callerIp = e.request().getHeader("x-forwarded-for");
|
||||||
|
if(callerIp==null)
|
||||||
|
callerIp=e.request().getRemoteHost();
|
||||||
|
|
||||||
|
boolean success = e.response().getStatus()<400;
|
||||||
|
|
||||||
|
if (context.container().configuration().mode()!=Mode.offline)
|
||||||
|
generateAccounting(caller,callerQualifier,callerIp==null?"UNKNOWN":callerIp , success, context);
|
||||||
|
|
||||||
|
long durationInMillis = System.currentTimeMillis()-startCallThreadLocal.get();
|
||||||
|
|
||||||
|
Metrics.globalRegistry.timer("http.requests", "response",Integer.toString(e.response().getStatus())
|
||||||
|
, "context", ScopeProvider.instance.get(), "result", success?"SUCCEDED":"FAILED", "caller-ip", callerIp,
|
||||||
|
"caller-username", caller, "service-class", context.configuration().serviceClass(), "service-name", context.configuration().name(),
|
||||||
|
"method", InnerMethodName.instance.get()).record(durationInMillis, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
log.info("REQUEST SERVED ON {}:{}({}) CALLED FROM {}@{} IN SCOPE {} {}(CODE {}) IN {} millis",
|
||||||
|
context.configuration().name(),context.configuration().serviceClass(), InnerMethodName.instance.get(),
|
||||||
|
caller, callerIp, ScopeProvider.instance.get(), success?"SUCCEDED":"FAILED", e.response().getStatus(),durationInMillis);
|
||||||
|
startCallThreadLocal.remove();
|
||||||
|
InnerMethodName.instance.reset();
|
||||||
|
if (resetScope)
|
||||||
|
ScopeProvider.instance.reset();
|
||||||
|
}catch (Exception e1) {
|
||||||
|
log.error("error on accounting",e);
|
||||||
|
throw e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
String caller = SecretManagerProvider.instance.get().getUser().getUsername();
|
|
||||||
String callerQualifier = "UNKNOWN";
|
|
||||||
//retieves caller Ip when there is a proxy
|
|
||||||
String callerIp = e.request().getHeader("x-forwarded-for");
|
|
||||||
if(callerIp==null)
|
|
||||||
callerIp=e.request().getRemoteHost();
|
|
||||||
|
|
||||||
boolean success = e.response().getStatus()<400;
|
|
||||||
|
|
||||||
if (context.container().configuration().mode()!=Mode.offline)
|
|
||||||
generateAccounting(caller,callerQualifier,callerIp==null?"UNKNOWN":callerIp , success, context);
|
|
||||||
|
|
||||||
log.info("REQUEST SERVED ON {}:{}({}) CALLED FROM {}@{} IN SCOPE {} {}(CODE {}) IN {} millis",
|
|
||||||
context.configuration().name(),context.configuration().serviceClass(), InnerMethodName.instance.get(),
|
|
||||||
caller, callerIp, ScopeProvider.instance.get(), success?"SUCCEDED":"FAILED", e.response().getStatus(), System.currentTimeMillis()-startCallThreadLocal.get());
|
|
||||||
startCallThreadLocal.remove();
|
|
||||||
InnerMethodName.instance.reset();
|
|
||||||
if (resetScope)
|
|
||||||
ScopeProvider.instance.reset();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateAccounting(String caller, String callerQualifier, String remoteHost, boolean success, ApplicationContext context){
|
void generateAccounting(String caller, String callerQualifier, String remoteHost, boolean success, ApplicationContext context){
|
||||||
|
@ -91,20 +109,20 @@ public class RequestAccounting extends RequestHandler {
|
||||||
AccountingPersistence persistence = AccountingPersistenceFactory.getPersistence();
|
AccountingPersistence persistence = AccountingPersistenceFactory.getPersistence();
|
||||||
ServiceUsageRecord serviceUsageRecord = new ServiceUsageRecord();
|
ServiceUsageRecord serviceUsageRecord = new ServiceUsageRecord();
|
||||||
try{
|
try{
|
||||||
|
|
||||||
serviceUsageRecord.setConsumerId(caller);
|
serviceUsageRecord.setConsumerId(caller);
|
||||||
serviceUsageRecord.setCallerQualifier(callerQualifier);
|
serviceUsageRecord.setCallerQualifier(callerQualifier);
|
||||||
serviceUsageRecord.setScope(ScopeProvider.instance.get());
|
serviceUsageRecord.setScope(ScopeProvider.instance.get());
|
||||||
serviceUsageRecord.setServiceClass(context.configuration().serviceClass());
|
serviceUsageRecord.setServiceClass(context.configuration().serviceClass());
|
||||||
serviceUsageRecord.setServiceName(context.configuration().name());
|
serviceUsageRecord.setServiceName(context.configuration().name());
|
||||||
|
|
||||||
serviceUsageRecord.setHost(context.container().configuration().hostname()+":"+context.container().configuration().port());
|
serviceUsageRecord.setHost(context.container().configuration().hostname()+":"+context.container().configuration().port());
|
||||||
serviceUsageRecord.setCalledMethod(InnerMethodName.instance.get());
|
serviceUsageRecord.setCalledMethod(InnerMethodName.instance.get());
|
||||||
serviceUsageRecord.setCallerHost(remoteHost);
|
serviceUsageRecord.setCallerHost(remoteHost);
|
||||||
serviceUsageRecord.setOperationResult(success?OperationResult.SUCCESS:OperationResult.FAILED);
|
serviceUsageRecord.setOperationResult(success?OperationResult.SUCCESS:OperationResult.FAILED);
|
||||||
serviceUsageRecord.setDuration(System.currentTimeMillis()-startCallThreadLocal.get());
|
serviceUsageRecord.setDuration(System.currentTimeMillis()-startCallThreadLocal.get());
|
||||||
persistence.account(serviceUsageRecord);
|
persistence.account(serviceUsageRecord);
|
||||||
|
|
||||||
}catch(Exception ex){
|
}catch(Exception ex){
|
||||||
log.warn("invalid record passed to accounting ",ex);
|
log.warn("invalid record passed to accounting ",ex);
|
||||||
}
|
}
|
||||||
|
@ -115,6 +133,6 @@ public class RequestAccounting extends RequestHandler {
|
||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
package org.gcube.smartgears.handlers.application.request;
|
|
||||||
|
|
||||||
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 java.util.Base64;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
import org.gcube.common.authorization.utils.manager.SecretManager;
|
|
||||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
|
||||||
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.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.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);
|
|
||||||
|
|
||||||
private static final String BEARER_AUTH_PREFIX ="Bearer";
|
|
||||||
private static final String BASIC_AUTH_PREFIX ="Basic";
|
|
||||||
|
|
||||||
|
|
||||||
@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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
String retrievedUser = null;
|
|
||||||
String accessToken = null;
|
|
||||||
if (authHeader!=null && !authHeader.isEmpty()) {
|
|
||||||
if (authHeader.startsWith(BEARER_AUTH_PREFIX))
|
|
||||||
accessToken = authHeader.substring(BEARER_AUTH_PREFIX.length()).trim();
|
|
||||||
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()));
|
|
||||||
String[] splitAuth = decodedAuth.split(":");
|
|
||||||
token = splitAuth[1];
|
|
||||||
retrievedUser = splitAuth[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SecretManager secretManager = new SecretManager();
|
|
||||||
SecretManagerProvider.instance.set(secretManager);
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleResponse(ResponseEvent e) {
|
|
||||||
log.debug("resetting all the Thread local for this call.");
|
|
||||||
SecretManagerProvider.instance.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +1,37 @@
|
||||||
package org.gcube.smartgears.handlers.application.request;
|
package org.gcube.smartgears.handlers.application.request;
|
||||||
|
|
||||||
|
import static org.gcube.smartgears.Constants.token_header;
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.application_failed_error;
|
import static org.gcube.smartgears.handlers.application.request.RequestError.application_failed_error;
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.application_unavailable_error;
|
import static org.gcube.smartgears.handlers.application.request.RequestError.application_unavailable_error;
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.invalid_request_error;
|
import static org.gcube.smartgears.handlers.application.request.RequestError.invalid_request_error;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAttribute;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import org.gcube.common.authorization.utils.manager.SecretManager;
|
import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;
|
||||||
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
|
|
||||||
import org.gcube.common.scope.api.ScopeProvider;
|
import org.gcube.common.scope.api.ScopeProvider;
|
||||||
import org.gcube.common.scope.impl.ScopeBean;
|
import org.gcube.common.scope.impl.ScopeBean;
|
||||||
import org.gcube.common.scope.impl.ScopeBean.Type;
|
import org.gcube.common.scope.impl.ScopeBean.Type;
|
||||||
|
import org.gcube.common.security.providers.SecretManagerProvider;
|
||||||
|
import org.gcube.common.security.secrets.GCubeSecret;
|
||||||
|
import org.gcube.common.security.secrets.JWTSecret;
|
||||||
|
import org.gcube.common.security.secrets.Secret;
|
||||||
import org.gcube.smartgears.Constants;
|
import org.gcube.smartgears.Constants;
|
||||||
import org.gcube.smartgears.configuration.Mode;
|
import org.gcube.smartgears.configuration.Mode;
|
||||||
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
import org.gcube.smartgears.handlers.application.RequestEvent;
|
import org.gcube.smartgears.handlers.application.RequestEvent;
|
||||||
import org.gcube.smartgears.handlers.application.RequestHandler;
|
import org.gcube.smartgears.handlers.application.RequestHandler;
|
||||||
|
import org.gcube.smartgears.handlers.application.ResponseEvent;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@XmlRootElement(name = Constants.request_validation)
|
@XmlRootElement(name = Constants.request_validation)
|
||||||
public class RequestValidator extends RequestHandler {
|
public class RequestValidator extends RequestHandler {
|
||||||
|
|
||||||
@XmlAttribute(required=false, name="oauth")
|
|
||||||
@Deprecated
|
|
||||||
boolean oauthCompatibility = false;
|
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(RequestValidator.class);
|
private static Logger log = LoggerFactory.getLogger(RequestValidator.class);
|
||||||
|
|
||||||
|
private static final String BEARER_AUTH_PREFIX ="Bearer";
|
||||||
|
|
||||||
private ApplicationContext appContext;
|
private ApplicationContext appContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,7 +45,9 @@ public class RequestValidator extends RequestHandler {
|
||||||
log.trace("executing request validator ON REQUEST");
|
log.trace("executing request validator ON REQUEST");
|
||||||
|
|
||||||
appContext = call.context();
|
appContext = call.context();
|
||||||
|
|
||||||
|
SecretManagerProvider.instance.set(getSecret(call));
|
||||||
|
|
||||||
validateAgainstLifecycle(call);
|
validateAgainstLifecycle(call);
|
||||||
|
|
||||||
rejectUnauthorizedCalls(call);
|
rejectUnauthorizedCalls(call);
|
||||||
|
@ -54,6 +59,13 @@ public class RequestValidator extends RequestHandler {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleResponse(ResponseEvent e) {
|
||||||
|
log.debug("resetting all the Thread local for this call.");
|
||||||
|
SecretManagerProvider.instance.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void validateAgainstLifecycle(RequestEvent call) {
|
private void validateAgainstLifecycle(RequestEvent call) {
|
||||||
|
|
||||||
switch(appContext.lifecycle().state()) {
|
switch(appContext.lifecycle().state()) {
|
||||||
|
@ -68,7 +80,6 @@ public class RequestValidator extends RequestHandler {
|
||||||
//nothing to do, but avoids warnings
|
//nothing to do, but avoids warnings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateScopeCall() {
|
private void validateScopeCall() {
|
||||||
|
@ -92,10 +103,10 @@ public class RequestValidator extends RequestHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rejectUnauthorizedCalls(RequestEvent call){
|
private void rejectUnauthorizedCalls(RequestEvent call){
|
||||||
|
|
||||||
SecretManager secretManager = SecretManagerProvider.instance.get();
|
Secret secret = SecretManagerProvider.instance.get();
|
||||||
|
|
||||||
if (secretManager.getCurrentSecretHolder().getSecrets().size()>0){
|
if (secret!= null){
|
||||||
log.warn("rejecting call to {}, authorization required",appContext.name());
|
log.warn("rejecting call to {}, authorization required",appContext.name());
|
||||||
RequestError.request_not_authorized_error.fire(appContext.name()+": authorization required");
|
RequestError.request_not_authorized_error.fire(appContext.name()+": authorization required");
|
||||||
}
|
}
|
||||||
|
@ -109,8 +120,26 @@ public class RequestValidator extends RequestHandler {
|
||||||
private void validatePolicy(String scope, RequestEvent call){
|
private void validatePolicy(String scope, RequestEvent call){
|
||||||
//TODO: must be re-think
|
//TODO: must be re-think
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Secret getSecret(RequestEvent call){
|
||||||
|
String token = call.request().getParameter(token_header)==null? call.request().getHeader(token_header):call.request().getParameter(token_header);
|
||||||
|
String authHeader = call.request().getHeader(Constants.authorization_header);
|
||||||
|
|
||||||
|
log.trace("authorization header is {}",authHeader);
|
||||||
|
log.trace("token header is {}", token);
|
||||||
|
|
||||||
|
String accessToken = null;
|
||||||
|
if (authHeader!=null && !authHeader.isEmpty())
|
||||||
|
if (authHeader.startsWith(BEARER_AUTH_PREFIX))
|
||||||
|
accessToken = authHeader.substring(BEARER_AUTH_PREFIX.length()).trim();
|
||||||
|
|
||||||
|
Secret secret = null;
|
||||||
|
if (accessToken!=null)
|
||||||
|
secret = new JWTSecret(accessToken);
|
||||||
|
else if (token!=null)
|
||||||
|
secret = new GCubeSecret(token);
|
||||||
|
return secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.gcube.smartgears.handlers.container.ContainerLifecycleEvent;
|
||||||
import org.gcube.smartgears.handlers.container.ContainerPipeline;
|
import org.gcube.smartgears.handlers.container.ContainerPipeline;
|
||||||
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle;
|
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle;
|
||||||
import org.gcube.smartgears.lifecycle.container.ContainerState;
|
import org.gcube.smartgears.lifecycle.container.ContainerState;
|
||||||
import org.gcube.smartgears.security.AuthorizationProvider;
|
|
||||||
import org.gcube.smartgears.utils.Utils;
|
import org.gcube.smartgears.utils.Utils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class DefaultProvider implements Provider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
InputStream config = getClass().getResourceAsStream(container_handlers_file_path);
|
//TODO retrieve handler classes
|
||||||
|
|
||||||
if (config == null)
|
if (config == null)
|
||||||
throw new IllegalStateException("invalid distribution: cannot find " + container_handlers_file_path);
|
throw new IllegalStateException("invalid distribution: cannot find " + container_handlers_file_path);
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<profile-management />
|
<profile-management />
|
||||||
</lifecycle>
|
</lifecycle>
|
||||||
<request>
|
<request>
|
||||||
<context-retriever />
|
|
||||||
<request-validation />
|
<request-validation />
|
||||||
<request-accounting />
|
<request-accounting />
|
||||||
</request>
|
</request>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE xml>
|
||||||
|
<Resource>
|
||||||
|
<ID />
|
||||||
|
<Type>Service</Type>
|
||||||
|
<Profile>
|
||||||
|
<Description>${description}</Description>
|
||||||
|
<Class>${serviceClass}</Class>
|
||||||
|
<Name>common-smartgears</Name>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
<Packages>
|
||||||
|
<Software>
|
||||||
|
<Description>${description}</Description>
|
||||||
|
<Name>common-smartgears</Name>
|
||||||
|
<Version>4.0.0-SNAPSHOT</Version>
|
||||||
|
<MavenCoordinates>
|
||||||
|
<groupId>org.gcube.core</groupId>
|
||||||
|
<artifactId>common-smartgears</artifactId>
|
||||||
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
|
</MavenCoordinates>
|
||||||
|
<Type>Library</Type>
|
||||||
|
<Files>
|
||||||
|
<File>common-smartgears-4.0.0-SNAPSHOT.jar</File>
|
||||||
|
</Files>
|
||||||
|
</Software>
|
||||||
|
</Packages>
|
||||||
|
</Profile>
|
||||||
|
</Resource>
|
||||||
|
|
Loading…
Reference in New Issue