From a6b366e32a5177f1d524931e2d9eab7e5fcd989e Mon Sep 17 00:00:00 2001 From: "lucio.lelii" Date: Mon, 1 Feb 2016 14:14:44 +0000 Subject: [PATCH] git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/Common/authorization-common-client@122673 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../UnauthorizedAccessException.java | 20 ++++ .../client/helper/Authorizable.java | 8 ++ .../client/helper/Authorization.java | 101 ++++++++++++++++++ .../proxy/DefaultAuthorizationProxy.java | 8 +- .../authorizationservice/cl/CallTest.java | 5 +- 5 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/gcube/common/authorization/client/exceptions/UnauthorizedAccessException.java create mode 100644 src/main/java/org/gcube/common/authorization/client/helper/Authorizable.java create mode 100644 src/main/java/org/gcube/common/authorization/client/helper/Authorization.java diff --git a/src/main/java/org/gcube/common/authorization/client/exceptions/UnauthorizedAccessException.java b/src/main/java/org/gcube/common/authorization/client/exceptions/UnauthorizedAccessException.java new file mode 100644 index 0000000..d10229e --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/client/exceptions/UnauthorizedAccessException.java @@ -0,0 +1,20 @@ +package org.gcube.common.authorization.client.exceptions; + +public class UnauthorizedAccessException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -950230930130868466L; + + protected UnauthorizedAccessException() { + super(); + } + + public UnauthorizedAccessException(String message) { + super(message); + } + + + +} diff --git a/src/main/java/org/gcube/common/authorization/client/helper/Authorizable.java b/src/main/java/org/gcube/common/authorization/client/helper/Authorizable.java new file mode 100644 index 0000000..8eef113 --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/client/helper/Authorizable.java @@ -0,0 +1,8 @@ +package org.gcube.common.authorization.client.helper; + +public interface Authorizable { + + String getServiceName(); + + String getServiceClass(); +} diff --git a/src/main/java/org/gcube/common/authorization/client/helper/Authorization.java b/src/main/java/org/gcube/common/authorization/client/helper/Authorization.java new file mode 100644 index 0000000..9591a24 --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/client/helper/Authorization.java @@ -0,0 +1,101 @@ +package org.gcube.common.authorization.client.helper; + +import static org.gcube.common.authorization.client.Constants.authorizationService; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javassist.util.proxy.MethodHandler; +import javassist.util.proxy.ProxyFactory; +import javassist.util.proxy.ProxyObject; + +import org.gcube.common.authorization.client.exceptions.UnauthorizedAccessException; +import org.gcube.common.authorization.library.AuthorizationEntry; +import org.gcube.common.authorization.library.PolicyUtils; +import org.gcube.common.authorization.library.annotations.AuthorizationControl; +import org.gcube.common.authorization.library.policies.Mode; +import org.gcube.common.authorization.library.policies.Policy; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.authorization.library.provider.ServiceIdentifier; + + +/** + * enables authorization control on classes using proxies + * + * when a user in not allowed to call a method annotated with {@link AuthorizationControl} + * an {@link UnauthorizedAccessException} is thrown + * + * @author lucio lelii + * + */ +public class Authorization { + + private static Map, Class> proxyClassMap = new HashMap, Class>(); + + private static ProxyFactory proxyfactory = new ProxyFactory(); + + private static Class getProxied(Class proxyClass){ + if (proxyClassMap.containsKey(proxyClass)) + return proxyClassMap.get(proxyClass); + + proxyfactory.setSuperclass(proxyClass); + Class proxied=proxyfactory.createClass(); + proxyClassMap.put(proxyClass, proxied); + return proxied; + } + + public static T getAuthorizedInstance(Class proxyClass){ + Class proxied = getProxied(proxyClass); + + Object obj; + try { + obj = proxied.newInstance(); + MethodHandler handler = new MethodHandler() { + + public Object invoke(Object self, Method thisMethod, Method proceed, + Object[] args) throws Throwable { + if (thisMethod.isAnnotationPresent(AuthorizationControl.class) && !thisMethod.getName().equals("getServiceName") + && !thisMethod.getName().equals("getServiceClass")){ + if (SecurityTokenProvider.instance.get()==null) + throw new RuntimeException("the Security token is not set"); + Authorizable obj = (Authorizable) self; + Mode[] modes = null; + if (thisMethod.isAnnotationPresent(AuthorizationControl.class)) + modes = thisMethod.getAnnotation(AuthorizationControl.class).check(); + checkAuthorization(obj.getServiceClass(), obj.getServiceName(), modes); + } + return proceed.invoke(self, args); + } + }; + ((ProxyObject)obj).setHandler(handler); + return proxyClass.cast(obj); + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public static void checkAuthorization(String serviceClass, String serviceName, Mode ... modes) throws Exception{ + if (modes==null || modes.length==0) return; + if (SecurityTokenProvider.instance.get()==null) + throw new UnauthorizedAccessException("the Security token is not set"); + + List modesList = Arrays.asList(modes); + + AuthorizationEntry entry = authorizationService().get(SecurityTokenProvider.instance.get()); + + if (entry.getPolicies()!=null){ + //DO we need a library identifier ?? + ServiceIdentifier serviceIdentifier = new ServiceIdentifier(serviceClass, serviceName, "*"); + for (Policy policy: entry.getPolicies()) + if (PolicyUtils.isPolicyValidForClient(policy.getServiceAccess(), serviceIdentifier)) + if (modesList.contains(policy.getMode()) || policy.getMode()==Mode.ALL) + throw new UnauthorizedAccessException("the invoked method is protected by the Authorization system, cannot be invoked by "+entry.getClientInfo().getId()); + + } + } + + +} diff --git a/src/main/java/org/gcube/common/authorization/client/proxy/DefaultAuthorizationProxy.java b/src/main/java/org/gcube/common/authorization/client/proxy/DefaultAuthorizationProxy.java index e8b52d9..4f6b0f1 100644 --- a/src/main/java/org/gcube/common/authorization/client/proxy/DefaultAuthorizationProxy.java +++ b/src/main/java/org/gcube/common/authorization/client/proxy/DefaultAuthorizationProxy.java @@ -7,7 +7,6 @@ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; @@ -15,8 +14,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; + import org.gcube.common.authorization.client.Binder; import org.gcube.common.authorization.client.Constants; import org.gcube.common.authorization.client.exceptions.ObjectNotFound; @@ -26,7 +24,6 @@ import org.gcube.common.authorization.library.enpoints.AuthorizationEndpoint; import org.gcube.common.authorization.library.enpoints.AuthorizationEndpointScanner; import org.gcube.common.authorization.library.policies.Policy; import org.gcube.common.authorization.library.provider.ClientInfo; -import org.gcube.common.authorization.library.provider.ServiceInfo; import org.gcube.common.authorization.library.provider.UserInfo; import org.gcube.common.encryption.StringEncrypter; import org.gcube.common.scope.api.ScopeProvider; @@ -93,6 +90,9 @@ public class DefaultAuthorizationProxy implements AuthorizationProxy { @Override public AuthorizationEntry get(String token) throws ObjectNotFound, Exception{ + if (cache.containsKey(token) && cache.get(token).isValid()) + return cache.get(token).getEntry(); + final String methodPath = "/retrieve/"; StringBuilder callUrl = new StringBuilder(getInternalEnpoint()).append(methodPath).append(token); diff --git a/src/test/java/org/gcube/common/authorizationservice/cl/CallTest.java b/src/test/java/org/gcube/common/authorizationservice/cl/CallTest.java index 7eba886..9dba4bd 100644 --- a/src/test/java/org/gcube/common/authorizationservice/cl/CallTest.java +++ b/src/test/java/org/gcube/common/authorizationservice/cl/CallTest.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import org.gcube.common.authorization.client.exceptions.ObjectNotFound; +import org.gcube.common.authorization.library.policies.Mode; import org.gcube.common.authorization.library.policies.Policy; import org.gcube.common.authorization.library.policies.ServiceAccess; import org.gcube.common.authorization.library.policies.User; @@ -36,7 +37,7 @@ public class CallTest { @Test public void addPolicy() throws Exception { List policies = new ArrayList(); - policies.add(new User2ServicePolicy("/gcube/devsec", new ServiceAccess(), new User("lucio.lelii") )); + policies.add(new User2ServicePolicy("/gcube/devsec", new ServiceAccess(), new User("lucio.lelii"), Mode.ACCESS )); authorizationService().addPolicies(policies); } @@ -48,6 +49,6 @@ public class CallTest { @Test public void removePolicy() throws Exception { - authorizationService().removePolicies(3); + authorizationService().removePolicies(2, 3, 4); } }