SEC-1387: Support serialization of security advised beans.

MethodSecurityMetadataSourceAdvisor now takes the SecurityMetadataSource bean name as an extra constructor argument and re-obtains the bean from the BeanFactory in its readObject method. Beans that are advised using <global-method-security> should therefore now be serializable.
This commit is contained in:
Luke Taylor
2010-02-19 00:38:24 +00:00
parent 14ae36ac3b
commit 10dc72b017
4 changed files with 73 additions and 19 deletions

View File

@@ -1,11 +1,18 @@
package org.springframework.security.config.method;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.annotation.BusinessService;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.ConfigTestUtils;
import org.springframework.security.config.util.InMemoryXmlApplicationContext;
@@ -60,4 +67,39 @@ public class SecuredAnnotationDrivenBeanDefinitionParserTests {
target.someAdminMethod();
}
// SEC-1387
@Test(expected=AuthenticationCredentialsNotFoundException.class)
public void targetIsSerializableBeforeUse() throws Exception {
BusinessService chompedTarget = (BusinessService) serializeAndDeserialize(target);
chompedTarget.someAdminMethod();
}
@Test(expected=AccessDeniedException.class)
public void targetIsSerializableAfterUse() throws Exception {
try {
target.someAdminMethod();
} catch (AuthenticationCredentialsNotFoundException expected) {
}
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("u","p","ROLE_A"));
BusinessService chompedTarget = (BusinessService) serializeAndDeserialize(target);
chompedTarget.someAdminMethod();
}
private Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.flush();
baos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(is);
Object o2 = ois.readObject();
return o2;
}
}