10 changed files with 406 additions and 1 deletions
@ -0,0 +1,66 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-parent</artifactId> |
||||||
|
<version>3.0.0.CI-SNAPSHOT</version> |
||||||
|
</parent> |
||||||
|
<packaging>jar</packaging> |
||||||
|
<artifactId>spring-security-aspects</artifactId> |
||||||
|
<name>Spring Security - Aspects</name> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>commons-logging</groupId> |
||||||
|
<artifactId>commons-logging</artifactId> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.aspectj</groupId> |
||||||
|
<artifactId>aspectjweaver</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-core</artifactId> |
||||||
|
<version>3.0.0.CI-SNAPSHOT</version> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
<build> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.codehaus.mojo</groupId> |
||||||
|
<artifactId>aspectj-maven-plugin</artifactId> |
||||||
|
<version>1.0</version> |
||||||
|
<dependencies> |
||||||
|
<!-- |
||||||
|
NB: You must use Maven 2.0.9 or above or these |
||||||
|
are ignored (see MNG-2972) |
||||||
|
--> |
||||||
|
<dependency> |
||||||
|
<groupId>org.aspectj</groupId> |
||||||
|
<artifactId>com.springsource.org.aspectj.runtime</artifactId> |
||||||
|
<version>1.6.3.RELEASE</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.aspectj</groupId> |
||||||
|
<artifactId>com.springsource.org.aspectj.tools</artifactId> |
||||||
|
<version>1.6.3.RELEASE</version> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
<executions> |
||||||
|
<execution> |
||||||
|
<goals> |
||||||
|
<goal>compile</goal> |
||||||
|
<goal>test-compile</goal> |
||||||
|
</goals> |
||||||
|
</execution> |
||||||
|
</executions> |
||||||
|
<configuration> |
||||||
|
<source>1.6</source> |
||||||
|
<target>1.6</target> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
</project> |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
package org.springframework.security.access.intercept.aspectj.aspect; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean; |
||||||
|
import org.springframework.security.access.annotation.Secured; |
||||||
|
import org.springframework.security.access.intercept.aspectj.AspectJCallback; |
||||||
|
import org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor; |
||||||
|
|
||||||
|
/** |
||||||
|
* Concrete AspectJ transaction aspect using Spring Security @Secured annotation |
||||||
|
* for JDK 1.5+. |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* When using this aspect, you <i>must</i> annotate the implementation class |
||||||
|
* (and/or methods within that class), <i>not</i> the interface (if any) that |
||||||
|
* the class implements. AspectJ follows Java's rule that annotations on |
||||||
|
* interfaces are <i>not</i> inherited. This will vary from Spring AOP. |
||||||
|
* |
||||||
|
* @author Mike Wiesner |
||||||
|
* @since 1.0 |
||||||
|
* @version $Id$ |
||||||
|
*/ |
||||||
|
public aspect AnnotationSecurityAspect implements InitializingBean { |
||||||
|
|
||||||
|
/** |
||||||
|
* Matches the execution of any public method in a type with the Secured |
||||||
|
* annotation, or any subtype of a type with the Secured annotation. |
||||||
|
*/ |
||||||
|
private pointcut executionOfAnyPublicMethodInAtSecuredType() : |
||||||
|
execution(public * ((@Secured *)+).*(..)) && @this(Secured); |
||||||
|
|
||||||
|
/** |
||||||
|
* Matches the execution of any method with the Secured annotation. |
||||||
|
*/ |
||||||
|
private pointcut executionOfSecuredMethod() : |
||||||
|
execution(* *(..)) && @annotation(Secured); |
||||||
|
|
||||||
|
private pointcut securedMethodExecution() : |
||||||
|
executionOfAnyPublicMethodInAtSecuredType() || |
||||||
|
executionOfSecuredMethod(); |
||||||
|
|
||||||
|
private AspectJSecurityInterceptor securityInterceptor; |
||||||
|
|
||||||
|
Object around(): securedMethodExecution() { |
||||||
|
if (this.securityInterceptor == null) { |
||||||
|
return proceed(); |
||||||
|
} |
||||||
|
|
||||||
|
AspectJCallback callback = new AspectJCallback() { |
||||||
|
public Object proceedWithObject() { |
||||||
|
return proceed(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return this.securityInterceptor.invoke(thisJoinPoint, callback); |
||||||
|
} |
||||||
|
|
||||||
|
public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) { |
||||||
|
this.securityInterceptor = securityInterceptor; |
||||||
|
} |
||||||
|
|
||||||
|
public void afterPropertiesSet() throws Exception { |
||||||
|
if (this.securityInterceptor == null) |
||||||
|
throw new IllegalArgumentException("securityInterceptor required"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
<?xml version="1.0"?> |
||||||
|
|
||||||
|
<!-- |
||||||
|
AspectJ load-time weaving config file to install common Spring |
||||||
|
aspects. |
||||||
|
--> |
||||||
|
<aspectj> |
||||||
|
|
||||||
|
<!-- |
||||||
|
<weaver options="-showWeaveInfo"/> |
||||||
|
--> |
||||||
|
|
||||||
|
<aspects> |
||||||
|
<aspect |
||||||
|
name="org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect" /> |
||||||
|
</aspects> |
||||||
|
|
||||||
|
</aspectj> |
||||||
@ -0,0 +1,89 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-parent</artifactId> |
||||||
|
<version>3.0.0.CI-SNAPSHOT</version> |
||||||
|
</parent> |
||||||
|
<artifactId>spring-security-samples-aspectj</artifactId> |
||||||
|
<packaging>jar</packaging> |
||||||
|
<name>Spring Security Sample AspectJ</name> |
||||||
|
<dependencies> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>junit</groupId> |
||||||
|
<artifactId>junit</artifactId> |
||||||
|
<version>4.6</version> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-core</artifactId> |
||||||
|
<version>${project.version}</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-aspects</artifactId> |
||||||
|
<version>${project.version}</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework</groupId> |
||||||
|
<artifactId>spring-test</artifactId> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
<build> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||||
|
<artifactId>maven-compiler-plugin</artifactId> |
||||||
|
<version>2.0.2</version> |
||||||
|
<configuration> |
||||||
|
<source>1.6</source> |
||||||
|
<target>1.6</target> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
<plugin> |
||||||
|
<groupId>org.codehaus.mojo</groupId> |
||||||
|
<artifactId>aspectj-maven-plugin</artifactId> |
||||||
|
<version>1.0</version> |
||||||
|
<dependencies> |
||||||
|
<!-- |
||||||
|
NB: You must use Maven 2.0.9 or above or these are ignored (see |
||||||
|
MNG-2972) |
||||||
|
--> |
||||||
|
<dependency> |
||||||
|
<groupId>org.aspectj</groupId> |
||||||
|
<artifactId>com.springsource.org.aspectj.runtime</artifactId> |
||||||
|
<version>1.6.3.RELEASE</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.aspectj</groupId> |
||||||
|
<artifactId>com.springsource.org.aspectj.tools</artifactId> |
||||||
|
<version>1.6.3.RELEASE</version> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
<executions> |
||||||
|
<execution> |
||||||
|
<goals> |
||||||
|
<goal>compile</goal> |
||||||
|
<goal>test-compile</goal> |
||||||
|
</goals> |
||||||
|
</execution> |
||||||
|
</executions> |
||||||
|
<configuration> |
||||||
|
<aspectLibraries> |
||||||
|
<aspectLibrary> |
||||||
|
<groupId>org.springframework.security</groupId> |
||||||
|
<artifactId>spring-security-aspects</artifactId> |
||||||
|
</aspectLibrary> |
||||||
|
</aspectLibraries> |
||||||
|
<source>1.6</source> |
||||||
|
<target>1.6</target> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
</project> |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
package sample.aspectj; |
||||||
|
|
||||||
|
import org.springframework.security.access.annotation.Secured; |
||||||
|
|
||||||
|
/** |
||||||
|
* Service which is secured on the class level |
||||||
|
* |
||||||
|
* @author Mike Wiesner |
||||||
|
* @since 3.0 |
||||||
|
* @version $Id$ |
||||||
|
*/ |
||||||
|
@Secured("ROLE_USER") |
||||||
|
public class SecuredService { |
||||||
|
|
||||||
|
public void secureMethod() { |
||||||
|
// nothing
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
package sample.aspectj; |
||||||
|
|
||||||
|
import org.springframework.security.access.annotation.Secured; |
||||||
|
|
||||||
|
/** |
||||||
|
* Service which is secured on method level |
||||||
|
* |
||||||
|
* @author Mike Wiesner |
||||||
|
* @since 1.0 |
||||||
|
* @version $Id$ |
||||||
|
*/ |
||||||
|
public class Service { |
||||||
|
|
||||||
|
@Secured("ROLE_USER") |
||||||
|
public void secureMethod() { |
||||||
|
// nothing
|
||||||
|
} |
||||||
|
|
||||||
|
public void publicMethod() { |
||||||
|
// nothing
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,44 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> |
||||||
|
|
||||||
|
<bean id="aspectJSecurityInterceptor" |
||||||
|
class="org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor"> |
||||||
|
<property name="authenticationManager" ref="authenticationManager" /> |
||||||
|
<property name="accessDecisionManager" ref="accessDecisionManager" /> |
||||||
|
<property name="securityMetadataSource"> |
||||||
|
<bean |
||||||
|
class="org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource" /> |
||||||
|
</property> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<bean id="authenticationManager" |
||||||
|
class="org.springframework.security.authentication.ProviderManager"> |
||||||
|
<property name="providers"> |
||||||
|
<bean |
||||||
|
class="org.springframework.security.authentication.TestingAuthenticationProvider" /> |
||||||
|
</property> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<bean id="accessDecisionManager" |
||||||
|
class="org.springframework.security.access.vote.AffirmativeBased"> |
||||||
|
<property name="decisionVoters"> |
||||||
|
<list> |
||||||
|
<bean |
||||||
|
class="org.springframework.security.access.vote.RoleVoter" /> |
||||||
|
</list> |
||||||
|
</property> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<bean |
||||||
|
class="org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect" |
||||||
|
factory-method="aspectOf"> |
||||||
|
<property name="securityInterceptor" ref="aspectJSecurityInterceptor" /> |
||||||
|
</bean> |
||||||
|
|
||||||
|
<bean class="sample.aspectj.Service" /> |
||||||
|
|
||||||
|
<bean class="sample.aspectj.SecuredService" /> |
||||||
|
|
||||||
|
</beans> |
||||||
@ -0,0 +1,78 @@ |
|||||||
|
package sample.aspectj; |
||||||
|
|
||||||
|
import org.junit.After; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.security.access.AccessDeniedException; |
||||||
|
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; |
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
||||||
|
import org.springframework.security.core.Authentication; |
||||||
|
import org.springframework.security.core.authority.AuthorityUtils; |
||||||
|
import org.springframework.security.core.context.SecurityContextHolder; |
||||||
|
import org.springframework.test.context.ContextConfiguration; |
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; |
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class) |
||||||
|
@ContextConfiguration(locations = "classpath:aspectj-context.xml") |
||||||
|
public class AspectJInterceptorTests { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private Service service; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private SecuredService securedService; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testPublicMethod() throws Exception { |
||||||
|
service.publicMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test(expected = AuthenticationCredentialsNotFoundException.class) |
||||||
|
public void testSecuredMethodNotAuthenticated() throws Exception { |
||||||
|
service.secureMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test(expected = AccessDeniedException.class) |
||||||
|
public void testSecuredMethodWrongRole() throws Exception { |
||||||
|
Authentication token = new UsernamePasswordAuthenticationToken("test", "xxx", AuthorityUtils |
||||||
|
.createAuthorityList("ROLE_ADMIN")); |
||||||
|
SecurityContextHolder.getContext().setAuthentication(token); |
||||||
|
service.secureMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testSecuredMethodEverythingOk() throws Exception { |
||||||
|
Authentication token = new UsernamePasswordAuthenticationToken("test", "xxx", AuthorityUtils |
||||||
|
.createAuthorityList("ROLE_USER")); |
||||||
|
SecurityContextHolder.getContext().setAuthentication(token); |
||||||
|
service.secureMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test(expected = AuthenticationCredentialsNotFoundException.class) |
||||||
|
public void testSecuredClassNotAuthenticated() throws Exception { |
||||||
|
securedService.secureMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test(expected = AccessDeniedException.class) |
||||||
|
public void testSecuredClassWrongRole() throws Exception { |
||||||
|
Authentication token = new UsernamePasswordAuthenticationToken("test", "xxx", AuthorityUtils |
||||||
|
.createAuthorityList("ROLE_ADMIN")); |
||||||
|
SecurityContextHolder.getContext().setAuthentication(token); |
||||||
|
securedService.secureMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testSecuredClassEverythingOk() throws Exception { |
||||||
|
Authentication token = new UsernamePasswordAuthenticationToken("test", "xxx", AuthorityUtils |
||||||
|
.createAuthorityList("ROLE_USER")); |
||||||
|
SecurityContextHolder.getContext().setAuthentication(token); |
||||||
|
securedService.secureMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
@After |
||||||
|
public void tearDown() { |
||||||
|
SecurityContextHolder.clearContext(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue