SEC-1158: Decoupling of Pre/Post annotations implementation from Spring EL.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package org.springframework.security.integration.python;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.prepost.PostInvocationAttribute;
|
||||
import org.springframework.security.access.prepost.PostInvocationAuthorizationAdvice;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
public class PythonInterpreterPostInvocationAdvice implements PostInvocationAuthorizationAdvice{
|
||||
|
||||
public Object after(Authentication authentication, MethodInvocation mi, PostInvocationAttribute pia,
|
||||
Object returnedObject) throws AccessDeniedException {
|
||||
return returnedObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.springframework.security.integration.python;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.python.core.Py;
|
||||
import org.python.core.PyObject;
|
||||
import org.python.util.PythonInterpreter;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.security.access.prepost.PreInvocationAttribute;
|
||||
import org.springframework.security.access.prepost.PreInvocationAuthorizationAdvice;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class PythonInterpreterPreInvocationAdvice implements PreInvocationAuthorizationAdvice{
|
||||
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
|
||||
|
||||
public boolean before(Authentication authentication, MethodInvocation mi, PreInvocationAttribute preAttr) {
|
||||
PythonInterpreterPreInvocationAttribute pythonAttr = (PythonInterpreterPreInvocationAttribute) preAttr;
|
||||
String script = pythonAttr.getScript();
|
||||
|
||||
PythonInterpreter python = new PythonInterpreter();
|
||||
python.set("authentication", authentication);
|
||||
python.set("args", createArgumentMap(mi));
|
||||
python.set("method", mi.getMethod().getName());
|
||||
Resource scriptResource = new PathMatchingResourcePatternResolver().getResource(script);
|
||||
|
||||
try {
|
||||
python.execfile(scriptResource.getInputStream());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("Couldn't run python script, " + script, e);
|
||||
}
|
||||
|
||||
PyObject allowed = python.get("allow");
|
||||
|
||||
if (allowed == null) {
|
||||
throw new IllegalStateException("Python script did not set the permit flag");
|
||||
}
|
||||
|
||||
return Py.tojava(allowed, Boolean.class);
|
||||
}
|
||||
|
||||
private Map<String,Object> createArgumentMap(MethodInvocation mi) {
|
||||
Object[] args = mi.getArguments();
|
||||
Object targetObject = mi.getThis();
|
||||
Method method = ClassUtils.getMostSpecificMethod(mi.getMethod(), targetObject.getClass());
|
||||
String[] paramNames = parameterNameDiscoverer.getParameterNames(method);
|
||||
|
||||
Map<String,Object> argMap = new HashMap<String,Object>();
|
||||
for(int i=0; i < args.length; i++) {
|
||||
argMap.put(paramNames[i], args[i]);
|
||||
}
|
||||
|
||||
return argMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.springframework.security.integration.python;
|
||||
|
||||
import org.springframework.security.access.prepost.PreInvocationAttribute;
|
||||
|
||||
public class PythonInterpreterPreInvocationAttribute implements PreInvocationAttribute {
|
||||
private String script;
|
||||
|
||||
PythonInterpreterPreInvocationAttribute(String script) {
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
public String getAttribute() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getScript() {
|
||||
return script;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.springframework.security.integration.python;
|
||||
|
||||
import org.python.util.PythonInterpreter;
|
||||
import org.springframework.security.access.prepost.PostAuthorize;
|
||||
import org.springframework.security.access.prepost.PostFilter;
|
||||
import org.springframework.security.access.prepost.PostInvocationAttribute;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.access.prepost.PreFilter;
|
||||
import org.springframework.security.access.prepost.PreInvocationAttribute;
|
||||
import org.springframework.security.access.prepost.PrePostInvocationAttributeFactory;
|
||||
|
||||
public class PythonInterpreterPrePostInvocationAttributeFactory implements PrePostInvocationAttributeFactory{
|
||||
|
||||
public PythonInterpreterPrePostInvocationAttributeFactory() {
|
||||
PythonInterpreter.initialize(System.getProperties(), null, new String[] {});
|
||||
}
|
||||
|
||||
|
||||
public PreInvocationAttribute createPreInvocationAttribute(PreFilter preFilter, PreAuthorize preAuthorize) {
|
||||
return new PythonInterpreterPreInvocationAttribute(preAuthorize.value());
|
||||
}
|
||||
|
||||
public PostInvocationAttribute createPostInvocationAttribute(PostFilter postFilter, PostAuthorize postAuthorize) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.springframework.security.integration.python;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
public interface TestService {
|
||||
|
||||
@PreAuthorize("someMethod.py")
|
||||
public void someMethod();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.springframework.security.integration.python;
|
||||
|
||||
public class TestServiceImpl implements TestService {
|
||||
|
||||
public void someMethod() {
|
||||
System.out.print("Invoked someMethod()");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.springframework.security.integration.python;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@ContextConfiguration(locations={"/python-method-access-app-context.xml"})
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class PythonInterpreterBasedSecurityTests {
|
||||
|
||||
@Autowired
|
||||
private TestService service;
|
||||
|
||||
@Test
|
||||
public void serviceMethod() throws Exception {
|
||||
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("bob","bobspassword"));
|
||||
|
||||
// for (int i=0; i < 1000; i++) {
|
||||
service.someMethod();
|
||||
// }
|
||||
}
|
||||
}
|
||||
32
itest/context/src/test/resources/python-method-access-app-context.xml
Executable file
32
itest/context/src/test/resources/python-method-access-app-context.xml
Executable file
@@ -0,0 +1,32 @@
|
||||
<b:beans xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:b="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
|
||||
|
||||
<global-method-security pre-post-annotations="enabled">
|
||||
<pre-post-annotation-handling>
|
||||
<invocation-attribute-factory ref="attributeFactory"/>
|
||||
<pre-invocation-advice ref="preAdvice"/>
|
||||
<post-invocation-advice ref="postAdvice"/>
|
||||
</pre-post-annotation-handling>
|
||||
</global-method-security>
|
||||
|
||||
<b:bean id="attributeFactory" class="org.springframework.security.integration.python.PythonInterpreterPrePostInvocationAttributeFactory"/>
|
||||
<b:bean id="preAdvice" class="org.springframework.security.integration.python.PythonInterpreterPreInvocationAdvice"/>
|
||||
<b:bean id="postAdvice" class="org.springframework.security.integration.python.PythonInterpreterPostInvocationAdvice"/>
|
||||
|
||||
<b:bean id="service" class="org.springframework.security.integration.python.TestServiceImpl"/>
|
||||
|
||||
<authentication-provider>
|
||||
<user-service>
|
||||
<user name="bob" password="bobspassword" authorities="ROLE_A,ROLE_B"/>
|
||||
</user-service>
|
||||
</authentication-provider>
|
||||
|
||||
</b:beans>
|
||||
@@ -1,30 +1,30 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
|
||||
|
||||
|
||||
<bean id="userRepository" class="org.springframework.security.integration.StubUserRepository"/>
|
||||
<bean id="userRepository" class="org.springframework.security.integration.StubUserRepository"/>
|
||||
|
||||
<security:authentication-provider
|
||||
user-service-ref="userDetailsService" />
|
||||
|
||||
<bean id="userDetailsService" class="org.springframework.security.integration.UserDetailsServiceImpl">
|
||||
<property name="userRepository" ref="userRepository"/>
|
||||
</bean>
|
||||
<security:authentication-provider
|
||||
user-service-ref="userDetailsService" />
|
||||
|
||||
<security:global-method-security>
|
||||
<security:protect-pointcut
|
||||
expression="execution(* org.springframework.security.integration.*Repository+.*(..))"
|
||||
access="ROLE_LOGGEDIN" />
|
||||
</security:global-method-security>
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
</beans>
|
||||
<bean id="userDetailsService" class="org.springframework.security.integration.UserDetailsServiceImpl">
|
||||
<property name="userRepository" ref="userRepository"/>
|
||||
</bean>
|
||||
|
||||
<security:global-method-security>
|
||||
<security:protect-pointcut
|
||||
expression="execution(* org.springframework.security.integration.*Repository+.*(..))"
|
||||
access="ROLE_LOGGEDIN" />
|
||||
</security:global-method-security>
|
||||
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
|
||||
|
||||
<security:authentication-provider>
|
||||
<security:user-service>
|
||||
|
||||
Reference in New Issue
Block a user