SEC-1158: Decoupling of Pre/Post annotations implementation from Spring EL.

This commit is contained in:
Luke Taylor
2009-05-11 05:18:20 +00:00
parent acd7dc1f2d
commit 14c4739605
84 changed files with 2489 additions and 2028 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -0,0 +1,9 @@
package org.springframework.security.integration.python;
public class TestServiceImpl implements TestService {
public void someMethod() {
System.out.print("Invoked someMethod()");
}
}

View File

@@ -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();
// }
}
}

View 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>

View File

@@ -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>

View File

@@ -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>