10 changed files with 406 additions and 1 deletions
@ -0,0 +1,66 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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