diff --git a/core/src/main/java/org/springframework/security/access/SecurityMetadataSource.java b/core/src/main/java/org/springframework/security/access/SecurityMetadataSource.java index b0633141fd..89b2e1cbd3 100644 --- a/core/src/main/java/org/springframework/security/access/SecurityMetadataSource.java +++ b/core/src/main/java/org/springframework/security/access/SecurityMetadataSource.java @@ -31,13 +31,12 @@ public interface SecurityMetadataSource extends AopInfrastructureBean { //~ Methods ======================================================================================================== /** - * Accesses the ConfigAttributes that apply to a given secure object. - *

- * Returns null if no attributes apply. + * Accesses the {@code ConfigAttribute}s that apply to a given secure object. * * @param object the object being secured * - * @return the attributes that apply to the passed in secured object or null if there are no applicable attributes. + * @return the attributes that apply to the passed in secured object. Can return either {@code null} or an + * empty collection if there are no applicable attributes. * * @throws IllegalArgumentException if the passed object is not of a type supported by the * SecurityMetadataSource implementation @@ -45,18 +44,18 @@ public interface SecurityMetadataSource extends AopInfrastructureBean { Collection getAttributes(Object object) throws IllegalArgumentException; /** - * If available, returns all of the ConfigAttributes defined by the implementing class. + * If available, returns all of the {@code ConfigAttribute}s defined by the implementing class. *

* This is used by the {@link AbstractSecurityInterceptor} to perform startup time validation of each - * ConfigAttribute configured against it. + * {@code ConfigAttribute} configured against it. * - * @return the ConfigAttributes or null if unsupported + * @return the {@code ConfigAttribute}s or {@code null} if unsupported */ Collection getAllConfigAttributes(); /** - * Indicates whether the SecurityMetadataSource implementation is able to provide - * ConfigAttributes for the indicated secure object type. + * Indicates whether the {@code SecurityMetadataSource} implementation is able to provide + * {@code ConfigAttribute}s for the indicated secure object type. * * @param clazz the class that is being queried * diff --git a/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java b/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java index e40172ac87..3a8e5a722e 100644 --- a/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java +++ b/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java @@ -170,7 +170,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A Collection attributes = this.obtainSecurityMetadataSource().getAttributes(object); - if (attributes == null) { + if (attributes == null || attributes.isEmpty()) { if (rejectPublicInvocations) { throw new IllegalArgumentException("Secure object invocation " + object + " was denied as public invocations are not allowed via this interceptor. " @@ -203,8 +203,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A this.accessDecisionManager.decide(authenticated, object, attributes); } catch (AccessDeniedException accessDeniedException) { - publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated, - accessDeniedException)); + publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated, accessDeniedException)); throw accessDeniedException; } @@ -266,8 +265,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A token.getAttributes(), returnedObject); } catch (AccessDeniedException accessDeniedException) { - AuthorizationFailureEvent event = new AuthorizationFailureEvent(token.getSecureObject(), token - .getAttributes(), token.getAuthentication(), accessDeniedException); + AuthorizationFailureEvent event = new AuthorizationFailureEvent(token.getSecureObject(), + token.getAttributes(), token.getAuthentication(), accessDeniedException); publishEvent(event); throw accessDeniedException; @@ -310,7 +309,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A /** * Helper method which generates an exception containing the passed reason, * and publishes an event to the application context. - *

+ *

* Always throws an exception. * * @param reason to be provided in the exception detail @@ -346,12 +345,12 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A /** * Indicates the type of secure objects the subclass will be presenting to * the abstract parent for processing. This is used to ensure collaborators - * wired to the AbstractSecurityInterceptor all support the + * wired to the {@code AbstractSecurityInterceptor} all support the * indicated secure object class. * * @return the type of secure object the subclass provides services for */ - public abstract Class getSecureObjectClass(); + public abstract Class getSecureObjectClass(); public boolean isAlwaysReauthenticate() { return alwaysReauthenticate; diff --git a/core/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java b/core/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java index 6f2bd62ef0..d12f7d2b80 100644 --- a/core/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java +++ b/core/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java @@ -15,54 +15,44 @@ package org.springframework.security.access.intercept; -import org.jmock.Expectations; -import org.jmock.Mockery; -import org.jmock.integration.junit4.JUnit4Mockery; +import static org.mockito.Mockito.mock; + import org.junit.Test; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.SecurityMetadataSource; -import org.springframework.security.access.intercept.AbstractSecurityInterceptor; -import org.springframework.security.access.intercept.RunAsManager; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.util.SimpleMethodInvocation; /** - * Tests some {@link AbstractSecurityInterceptor} methods. Most of the testing for this class is found in the - * MethodSecurityInterceptorTests class. + * Tests some {@link AbstractSecurityInterceptor} methods. Most of the testing for this class is found in the + * {@code MethodSecurityInterceptorTests} class. * * @author Ben Alex */ public class AbstractSecurityInterceptorTests { - private Mockery jmock = new JUnit4Mockery(); - //~ Methods ======================================================================================================== @Test(expected=IllegalArgumentException.class) public void detectsIfInvocationPassedIncompatibleSecureObject() throws Exception { MockSecurityInterceptorWhichOnlySupportsStrings si = new MockSecurityInterceptorWhichOnlySupportsStrings(); - si.setRunAsManager(jmock.mock(RunAsManager.class)); - si.setAuthenticationManager(jmock.mock(AuthenticationManager.class)); - si.setAfterInvocationManager(jmock.mock(AfterInvocationManager.class)); - si.setAccessDecisionManager(jmock.mock(AccessDecisionManager.class)); - si.setSecurityMetadataSource(jmock.mock(SecurityMetadataSource.class)); - - jmock.checking(new Expectations() {{ ignoring(anything()); }}); + si.setRunAsManager(mock(RunAsManager.class)); + si.setAuthenticationManager(mock(AuthenticationManager.class)); + si.setAfterInvocationManager(mock(AfterInvocationManager.class)); + si.setAccessDecisionManager(mock(AccessDecisionManager.class)); + si.setSecurityMetadataSource(mock(SecurityMetadataSource.class)); si.beforeInvocation(new SimpleMethodInvocation()); } @Test(expected=IllegalArgumentException.class) public void detectsViolationOfGetSecureObjectClassMethod() throws Exception { MockSecurityInterceptorReturnsNull si = new MockSecurityInterceptorReturnsNull(); - si.setRunAsManager(jmock.mock(RunAsManager.class)); - si.setAuthenticationManager(jmock.mock(AuthenticationManager.class)); - si.setAfterInvocationManager(jmock.mock(AfterInvocationManager.class)); - si.setAccessDecisionManager(jmock.mock(AccessDecisionManager.class)); - si.setSecurityMetadataSource(jmock.mock(SecurityMetadataSource.class)); - - jmock.checking(new Expectations() {{ ignoring(anything()); }}); - + si.setRunAsManager(mock(RunAsManager.class)); + si.setAuthenticationManager(mock(AuthenticationManager.class)); + si.setAfterInvocationManager(mock(AfterInvocationManager.class)); + si.setAccessDecisionManager(mock(AccessDecisionManager.class)); + si.setSecurityMetadataSource(mock(SecurityMetadataSource.class)); si.afterPropertiesSet(); } @@ -71,7 +61,7 @@ public class AbstractSecurityInterceptorTests { private class MockSecurityInterceptorReturnsNull extends AbstractSecurityInterceptor { private SecurityMetadataSource securityMetadataSource; - public Class getSecureObjectClass() { + public Class getSecureObjectClass() { return null; } @@ -87,7 +77,7 @@ public class AbstractSecurityInterceptorTests { private class MockSecurityInterceptorWhichOnlySupportsStrings extends AbstractSecurityInterceptor { private SecurityMetadataSource securityMetadataSource; - public Class getSecureObjectClass() { + public Class getSecureObjectClass() { return String.class; }