SEC-2015: Add spring-security-test

This commit is contained in:
Rob Winch 2014-04-22 16:47:48 -05:00
parent 1c75d33adb
commit 8baf82532c
48 changed files with 4647 additions and 10 deletions

View File

@ -22,4 +22,6 @@ dependencies {
runtime "opensymphony:sitemesh:2.4.2", runtime "opensymphony:sitemesh:2.4.2",
'cglib:cglib-nodep:2.2.2', 'cglib:cglib-nodep:2.2.2',
'ch.qos.logback:logback-classic:0.9.30' 'ch.qos.logback:logback-classic:0.9.30'
testCompile project(":spring-security-test")
} }

View File

@ -208,6 +208,12 @@
<version>1.9.5</version> <version>1.9.5</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.0.0.CI-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId> <artifactId>spring-test</artifactId>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -15,19 +15,126 @@
*/ */
package org.springframework.security.samples.config; package org.springframework.security.samples.config;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.samples.mvc.config.WebMvcConfiguration;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.test.context.support.WithSecurityContextTestExcecutionListener;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.test.context.web.ServletTestExecutionListener;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
/** /**
* @author Rob Winch * @author Rob Winch
* *
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=SecurityConfig.class) @ContextConfiguration(classes={RootConfiguration.class, WebMvcConfiguration.class})
@WebAppConfiguration
@TestExecutionListeners(listeners={ServletTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
WithSecurityContextTestExcecutionListener.class})
public class SecurityConfigTests { public class SecurityConfigTests {
private MockMvc mvc;
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.defaultRequest(get("/").with(testSecurityContext()))
.build();
}
@Test @Test
public void securityConfigurationLoads() {} public void requestProtectedResourceRequiresAuthentication() throws Exception {
mvc.perform(get("/"))
.andExpect(redirectedUrl("http://localhost/login"));
}
@Test
public void loginSuccess() throws Exception {
mvc.perform(formLogin())
.andExpect(redirectedUrl("/"));
}
@Test
public void loginFailure() throws Exception {
mvc.perform(formLogin().password("invalid"))
.andExpect(redirectedUrl("/login?error"));
}
@Test
@WithMockUser
public void requestProtectedResourceWithUser() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk());
}
@Test
@WithMockUser
public void composeMessageRequiresCsrfToken() throws Exception {
MockHttpServletRequestBuilder composeMessage =
post("/")
.param("summary", "New Message")
.param("text", "This is a new message");
mvc.perform(composeMessage)
.andExpect(status().isForbidden());
}
@Test
@WithMockUser
public void composeMessage() throws Exception {
MockHttpServletRequestBuilder composeMessage =
post("/")
.param("summary", "New Message")
.param("text", "This is a new message")
.with(csrf());
mvc.perform(composeMessage)
.andExpect(redirectedUrlPattern("/*"));
}
@Test
@WithMockUser
public void logoutRequiresCsrfToken() throws Exception {
mvc.perform(post("/logout"))
.andExpect(status().isForbidden());
}
@Test
@WithMockUser
public void logoutSuccess() throws Exception {
mvc.perform(logout())
.andExpect(redirectedUrl("/login?logout"))
.andExpect(unauthenticated());
}
} }

View File

@ -133,12 +133,6 @@
<version>4.0.2.RELEASE</version> <version>4.0.2.RELEASE</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId> <artifactId>spring-core</artifactId>
@ -151,6 +145,12 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId> <artifactId>spring-instrument</artifactId>

View File

@ -9,7 +9,8 @@ def String[] modules = [
'openid', 'openid',
'taglibs', 'taglibs',
'aspects', 'aspects',
'crypto' 'crypto',
'test'
] ]
def String[] samples = [ def String[] samples = [

132
test/pom.xml Normal file
View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.0.0.CI-SNAPSHOT</version>
<name>spring-security-test</name>
<description>spring-security-test</description>
<url>http://spring.io/spring-security</url>
<organization>
<name>spring.io</name>
<url>http://spring.io/</url>
</organization>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>rwinch</id>
<name>Rob Winch</name>
<email>rwinch@gopivotal.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/spring-projects/spring-security</connection>
<developerConnection>scm:git:git://github.com/spring-projects/spring-security</developerConnection>
<url>https://github.com/spring-projects/spring-security</url>
</scm>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snasphot</id>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.0.0.CI-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.0.0.CI-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.29</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.0.CI-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,110 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context;
import javax.servlet.FilterChain;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.test.context.support.WithSecurityContextTestExcecutionListener;
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.Assert;
/**
* The {@link TestSecurityContextHolder} is very similar to
* {@link SecurityContextHolder}, but is necessary for testing. For example, we
* cannot populate the desired {@link SecurityContext} in
* {@link SecurityContextHolder} for web based testing. In a web request, the
* {@link SecurityContextPersistenceFilter} will override the
* {@link SecurityContextHolder} with the value returned by the
* {@link SecurityContextRepository}. At the end of the {@link FilterChain} the
* {@link SecurityContextPersistenceFilter} will clear out the
* {@link SecurityContextHolder}. This means if we make multiple web requests,
* we will not know which {@link SecurityContext} to use on subsequent requests.
*
* Typical usage is as follows:
*
* <ul>
* <li>Before a test is executed, the {@link TestSecurityContextHolder} is
* populated. Typically this is done using the
* {@link WithSecurityContextTestExcecutionListener}</li>
* <li>The test is ran. When used with {@link MockMvc} it is typically used with
* {@link SecurityMockMvcRequestPostProcessors#testSecurityContext()}. Which ensures
* the {@link SecurityContext} from {@link TestSecurityContextHolder} is
* properly populated.</li>
* <li>After the test is executed, the {@link TestSecurityContextHolder} and the
* {@link SecurityContextHolder} are cleared out</li>
* </ul>
*
* @author Rob Winch
* @since 4.0
*
*/
public final class TestSecurityContextHolder {
private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<SecurityContext>();
/**
* Clears the {@link SecurityContext} from {@link TestSecurityContextHolder}
* and {@link SecurityContextHolder}.
*/
public static void clearContext() {
contextHolder.remove();
SecurityContextHolder.clearContext();
}
/**
* Gets the {@link SecurityContext} from {@link TestSecurityContextHolder}.
*
* @return the {@link SecurityContext} from {@link TestSecurityContextHolder}.
*/
public static SecurityContext getContext() {
SecurityContext ctx = contextHolder.get();
if (ctx == null) {
ctx = getDefaultContext();
contextHolder.set(ctx);
}
return ctx;
}
/**
* Sets the {@link SecurityContext} on {@link TestSecurityContextHolder} and {@link SecurityContextHolder}.
* @param context the {@link SecurityContext} to use
*/
public static void setContext(SecurityContext context) {
Assert.notNull(context,
"Only non-null SecurityContext instances are permitted");
contextHolder.set(context);
SecurityContextHolder.setContext(context);
}
/**
* Gets the default {@link SecurityContext} by delegating to the {@link SecurityContextHolder}
*
* @return the default {@link SecurityContext}
*/
private static SecurityContext getDefaultContext() {
return SecurityContextHolder.getContext();
}
private TestSecurityContextHolder() {
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.web.servlet.MockMvc;
/**
* When used with {@link WithSecurityContextTestExcecutionListener} this annotation can be
* added to a test method to emulate running with a mocked user. In order to work with {@link MockMvc} The
* {@link SecurityContext} that is used will have the following properties:
*
* <ul>
* <li>The {@link SecurityContext} created with be that of
* {@link SecurityContextHolder#createEmptyContext()}</li>
* <li>It will be populated with an {@link UsernamePasswordAuthenticationToken}
* that uses the username of either {@link #value()} or {@link #username()},
* {@link GrantedAuthority} that are specified by {@link #roles()}, and a
* password specified by {@link #password()}.
* </ul>
*
* @see WithUserDetails
*
* @author Rob Winch
* @since 4.0
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory = WithMockUserSecurityContextFactory.class)
public @interface WithMockUser {
/**
* Convenience mechanism for specifying the username. The default is "user". If {@link #username()} is specified it will be used instead of {@link #value()}
* @return
*/
String value() default "user";
/**
* The username to be used. Note that {@link #value()} is a synonym for {@link #username()}, but if {@link #username()} is specified it will take precedence.
* @return
*/
String username() default "";
/**
* The roles to use. The default is "USER". A {@link GrantedAuthority} will
* be created for each value within roles. Each value in roles will
* automatically be prefixed with "ROLE_". For example, the default will
* result in "ROLE_USER" being used.
*
* @return
*/
String[] roles() default { "USER" };
/**
* The password to be used. The default is "password".
* @return
*/
String password() default "password";
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.util.StringUtils;
/**
* A {@link WithUserDetailsSecurityContextFactory} that works with {@link WithMockUser}.
*
* @author Rob Winch
* @since 4.0
* @see WithMockUser
*/
final class WithMockUserSecurityContextFactory implements WithSecurityContextFactory<WithMockUser> {
public SecurityContext createSecurityContext(WithMockUser withUser) {
String username = StringUtils.hasLength(withUser.username()) ? withUser.username() : withUser.value();
if(username == null) {
throw new IllegalArgumentException(withUser + " cannot have null username on both username and value properites");
}
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for(String role : withUser.roles()) {
if(role.startsWith("ROLE_")) {
throw new IllegalArgumentException("roles cannot start with ROLE_ Got " + role);
}
authorities.add(new SimpleGrantedAuthority("ROLE_"+role));
}
User principal = new User(username, withUser.password(), true, true, true, true, authorities);
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities());
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
return context;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
/**
* <p>
* An annotation to determine what {@link SecurityContext} to use. The
* {@link #factory()} attribute must be provided with an instance of
* {@link WithUserDetailsSecurityContextFactory}.
* </p>
*
* <p>
* Typically this annotation will be used as an meta-annotation as done with
* {@link WithMockUser} and {@link WithUserDetails}.
* </p>
*
* <p>
* If you would like to create your own implementation of
* {@link WithSecurityContextFactory} you can do so by implementing the
* interface. You can also use {@link Autowired} and other Spring semantics on
* the {@link WithSecurityContextFactory} implementation.
* </p>
*
* @author Rob Winch
* @since 4.0
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface WithSecurityContext {
/**
* The {@link WithUserDetailsSecurityContextFactory} to use to create the {@link SecurityContext}. It can contain {@link Autowired} and other Spring annotations.
*
* @return
*/
Class<? extends WithSecurityContextFactory<? extends Annotation>> factory();
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import java.lang.annotation.Annotation;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.context.TestSecurityContextHolder;
/**
* An API that works with WithUserTestExcecutionListener for creating a
* {@link SecurityContext} that is populated in the
* {@link TestSecurityContextHolder}.
*
* @author Rob Winch
*
* @param <A>
* @see WithSecurityContext
* @see WithMockUser
* @see WithUserDetails
* @since 4.0
*/
public interface WithSecurityContextFactory<A extends Annotation> {
/**
* Create a {@link SecurityContext} given an Annotation.
*
* @param annotation
* the {@link Annotation} to create the {@link SecurityContext}
* from. Cannot be null.
* @return the {@link SecurityContext} to use. Cannot be null.
*/
SecurityContext createSecurityContext(A annotation);
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import java.lang.annotation.Annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.AbstractTestExecutionListener;
import org.springframework.test.web.servlet.MockMvc;
/**
* A {@link TestExecutionListener} that will find annotations that are annotated
* with {@link WithSecurityContext} on a test method or at the class level. If found, the
* {@link WithSecurityContext#factory()} is used to create a {@link SecurityContext} that
* will be used with this test. If using with {@link MockMvc} the
* {@link SecurityMockMvcRequestPostProcessors#testSecurityContext()} needs to be used
* too.
*
* @author Rob Winch
* @since 4.0
*/
public class WithSecurityContextTestExcecutionListener extends
AbstractTestExecutionListener {
/**
* Sets up the {@link SecurityContext} for each test method. First the
* specific method is inspected for a {@link WithSecurityContext} or {@link Annotation}
* that has {@link WithSecurityContext} on it. If that is not found, the class is
* inspected. If still not found, then no {@link SecurityContext} is
* populated.
*/
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
Annotation[] methodAnnotations = AnnotationUtils
.getAnnotations(testContext.getTestMethod());
ApplicationContext context = testContext.getApplicationContext();
SecurityContext securityContext = createSecurityContext(
methodAnnotations, context);
if (securityContext == null) {
Annotation[] classAnnotations = testContext.getTestClass()
.getAnnotations();
securityContext = createSecurityContext(classAnnotations, context);
}
if (securityContext != null) {
TestSecurityContextHolder.setContext(securityContext);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private SecurityContext createSecurityContext(Annotation[] annotations,
ApplicationContext context) {
for (Annotation a : annotations) {
WithSecurityContext withUser = AnnotationUtils.findAnnotation(
a.annotationType(), WithSecurityContext.class);
if (withUser != null) {
WithSecurityContextFactory factory = createFactory(
withUser, context);
try {
return factory.createSecurityContext(a);
} catch (RuntimeException e) {
throw new IllegalStateException("Unable to create SecurityContext using "+ a, e);
}
}
}
return null;
}
private WithSecurityContextFactory<? extends Annotation> createFactory(
WithSecurityContext withUser, ApplicationContext context) {
Class<? extends WithSecurityContextFactory<? extends Annotation>> clazz = withUser
.factory();
try {
return context.getAutowireCapableBeanFactory().createBean(clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Clears out the {@link TestSecurityContextHolder} and the
* {@link SecurityContextHolder} after each test method.
*/
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
TestSecurityContextHolder.clearContext();
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.test.web.servlet.MockMvc;
/**
* When used with {@link WithSecurityContextTestExcecutionListener} this annotation can be
* added to a test method to emulate running with a {@link UserDetails} returned
* from the {@link UserDetailsService}. In order to work with {@link MockMvc}
* The {@link SecurityContext} that is used will have the following properties:
*
* <ul>
* <li>The {@link SecurityContext} created with be that of
* {@link SecurityContextHolder#createEmptyContext()}</li>
* <li>It will be populated with an {@link UsernamePasswordAuthenticationToken}
* that uses the username of either {@link #value()} or {@link #username()},
* {@link GrantedAuthority} that are specified by {@link #roles()}, and a
* password specified by {@link #password()}.
* </ul>
*
* @see WithMockUser
*
* @author Rob Winch
* @since 4.0
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory=WithUserDetailsSecurityContextFactory.class)
public @interface WithUserDetails {
/**
* The username to look up in the {@link UserDetailsService}
*
* @return
*/
String value() default "user";
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.util.Assert;
/**
* A {@link WithUserDetailsSecurityContextFactory} that works with {@link WithUserDetails}.
*
* @see WithUserDetails
*
* @author Rob Winch
* @since 4.0
*/
final class WithUserDetailsSecurityContextFactory implements WithSecurityContextFactory<WithUserDetails> {
private UserDetailsService userDetailsService;
@Autowired
public WithUserDetailsSecurityContextFactory(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
public SecurityContext createSecurityContext(WithUserDetails withUser) {
String username = withUser.value();
Assert.hasLength(username, "value() must be non empty String");
UserDetails principal = userDetailsService.loadUserByUsername(username);
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities());
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
return context;
}
}

View File

@ -0,0 +1,213 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import javax.servlet.ServletContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
/**
* Contains Spring Security related {@link MockMvc} {@link RequestBuilder}s.
*
* @author Rob Winch
* @since 4.0
*
*/
public final class SecurityMockMvcRequestBuilders {
/**
* Creates a request (including any necessary {@link CsrfToken}) that will
* submit a form based login to POST "/login".
*
* @return the FormLoginRequestBuilder for further customizations
*/
public static FormLoginRequestBuilder formLogin() {
return new FormLoginRequestBuilder();
}
/**
* Creates a request (including any necessary {@link CsrfToken}) that will
* submit a form based login to POST {@code loginProcessingUrl}.
*
* @param loginProcessingUrl
* the URL to POST to
*
* @return the FormLoginRequestBuilder for further customizations
*/
public static FormLoginRequestBuilder formLogin(String loginProcessingUrl) {
return formLogin().loginProcessingUrl(loginProcessingUrl);
}
/**
* Creates a logout request.
*
* @return the LogoutRequestBuilder for additional customizations
*/
public static LogoutRequestBuilder logout() {
return new LogoutRequestBuilder();
}
/**
* Creates a logout request (including any necessary {@link CsrfToken}) to
* the specified {@code logoutUrl}
*
* @return the LogoutRequestBuilder for additional customizations
*/
public static LogoutRequestBuilder logout(String logoutUrl) {
return new LogoutRequestBuilder().logoutUrl(logoutUrl);
}
/**
* Creates a logout request (including any necessary {@link CsrfToken})
*
* @author Rob Winch
* @since 4.0
*/
public static final class LogoutRequestBuilder implements RequestBuilder {
private String logoutUrl = "/logout";
private RequestPostProcessor postProcessor = csrf();
public MockHttpServletRequest buildRequest(ServletContext servletContext) {
MockHttpServletRequest request = post(logoutUrl)
.buildRequest(servletContext);
return postProcessor.postProcessRequest(request);
}
/**
* Specifies the logout URL to POST to. Defaults to "/logout".
*
* @param logoutUrl the logout URL to POST to. Defaults to "/logout".
* @return the {@link LogoutRequestBuilder} for additional customizations
*/
public LogoutRequestBuilder logoutUrl(String logoutUrl) {
this.logoutUrl = logoutUrl;
return this;
}
private LogoutRequestBuilder() {}
}
/**
* Creates a form based login request including any necessary {@link CsrfToken}.
*
* @author Rob Winch
* @since 4.0
*/
public static final class FormLoginRequestBuilder implements RequestBuilder {
private String usernameParam = "username";
private String passwordParam = "password";
private String username = "user";
private String password = "password";
private String loginProcessingUrl = "/login";
private RequestPostProcessor postProcessor = csrf();
public MockHttpServletRequest buildRequest(ServletContext servletContext) {
MockHttpServletRequest request = post(loginProcessingUrl)
.param(usernameParam,username)
.param(passwordParam, password)
.buildRequest(servletContext);
return postProcessor.postProcessRequest(request);
}
/**
* Specifies the URL to POST to. Default is "/login"
*
* @param loginProcessingUrl the URL to POST to. Default is "/login"
* @return
*/
public FormLoginRequestBuilder loginProcessingUrl(String loginProcessingUrl) {
this.loginProcessingUrl = loginProcessingUrl;
return this;
}
/**
* The HTTP parameter to place the username. Default is "username".
* @param usernameParameter the HTTP parameter to place the username. Default is "username".
* @return the {@link FormLoginRequestBuilder} for additional customizations
*/
public FormLoginRequestBuilder userParameter(String usernameParameter) {
this.usernameParam = usernameParameter;
return this;
}
/**
* The HTTP parameter to place the password. Default is "password".
* @param passwordParameter the HTTP parameter to place the password. Default is "password".
* @return the {@link FormLoginRequestBuilder} for additional customizations
*/
public FormLoginRequestBuilder passwordParam(String passwordParameter) {
this.passwordParam = passwordParameter;
return this;
}
/**
* The value of the password parameter. Default is "password".
* @param password the value of the password parameter. Default is "password".
* @return the {@link FormLoginRequestBuilder} for additional customizations
*/
public FormLoginRequestBuilder password(String password) {
this.password = password;
return this;
}
/**
* The value of the username parameter. Default is "user".
* @param username the value of the username parameter. Default is "user".
* @return the {@link FormLoginRequestBuilder} for additional customizations
*/
public FormLoginRequestBuilder user(String username) {
this.username = username;
return this;
}
/**
* Specify both the password parameter name and the password.
*
* @param passwordParameter the HTTP parameter to place the password. Default is "password".
* @param password the value of the password parameter. Default is "password".
* @return the {@link FormLoginRequestBuilder} for additional customizations
*/
public FormLoginRequestBuilder password(String passwordParameter, String password) {
passwordParam(passwordParameter);
this.password = password;
return this;
}
/**
* Specify both the password parameter name and the password.
*
* @param usernameParameter the HTTP parameter to place the username. Default is "username".
* @param username the value of the username parameter. Default is "user".
* @return the {@link FormLoginRequestBuilder} for additional customizations
*/
public FormLoginRequestBuilder user(String usernameParameter, String username) {
userParameter(usernameParameter);
this.username = username;
return this;
}
private FormLoginRequestBuilder() {}
}
private SecurityMockMvcRequestBuilders() {}
}

View File

@ -0,0 +1,491 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.util.Assert;
/**
* Contains {@link MockMvc} {@link RequestPostProcessor} implementations for
* Spring Security.
*
* @author Rob Winch
* @since 4.0
*/
public final class SecurityMockMvcRequestPostProcessors {
/**
* Creates a {@link RequestPostProcessor} that will automatically populate a
* valid {@link CsrfToken} in the request.
*
* @return the {@link CsrfRequestPostProcessor} for further customizations.
*/
public static CsrfRequestPostProcessor csrf() {
return new CsrfRequestPostProcessor();
}
/**
* Creates a {@link RequestPostProcessor} that can be used to ensure that
* the resulting request is ran with the user in the
* {@link TestSecurityContextHolder}.
*
* @return the {@link RequestPostProcessor} to sue
*/
public static RequestPostProcessor testSecurityContext() {
return new TestSecurityContextHolderPostProcessor();
}
/**
* Establish a {@link SecurityContext} that has a
* {@link UsernamePasswordAuthenticationToken} for the
* {@link Authentication#getPrincipal()} and a {@link User} for the
* {@link UsernamePasswordAuthenticationToken#getPrincipal()}. All details
* are declarative and do not require that the user actually exists.
*
* @param username
* the username to populate
* @return the {@link UserRequestPostProcessor} for additional customization
*/
public static UserRequestPostProcessor user(String username) {
return new UserRequestPostProcessor(username);
}
/**
* Establish a {@link SecurityContext} that has a
* {@link UsernamePasswordAuthenticationToken} for the
* {@link Authentication#getPrincipal()} and a custom {@link UserDetails}
* for the {@link UsernamePasswordAuthenticationToken#getPrincipal()}. All
* details are declarative and do not require that the user actually exists.
*
* @param user
* the UserDetails to populate
* @return the {@link RequestPostProcessor} to use
*/
public static RequestPostProcessor user(UserDetails user) {
return new UserDetailsRequestPostProcessor(user);
}
/**
* Establish a {@link SecurityContext} that uses the specified {@link Authentication} for the
* {@link Authentication#getPrincipal()} and a custom {@link UserDetails}. All
* details are declarative and do not require that the user actually exists.
*
* @param user
* the UserDetails to populate
* @return the {@link RequestPostProcessor} to use
*/
public static RequestPostProcessor authentication(
Authentication authentication) {
return new AuthenticationRequestPostProcessor(authentication);
}
/**
* Establish the specified {@link SecurityContext} to be used.
*/
public static RequestPostProcessor securityContext(
SecurityContext securityContext) {
return new SecurityContextRequestPostProcessor(securityContext);
}
/**
* Convenience mechanism for setting the Authorization header to use HTTP
* Basic with the given username and password. This method will
* automatically perform the necessary Base64 encoding.
*
* @param username
* the username to include in the Authorization header.
* @param password the password to include in the Authorization header.
* @return the {@link RequestPostProcessor} to use
*/
public static RequestPostProcessor httpBasic(String username, String password) {
return new HttpBasicRequestPostProcessor(username, password);
}
/**
* Populates a valid {@link CsrfToken} into the request.
*
* @author Rob Winch
* @since 4.0
*/
public static class CsrfRequestPostProcessor implements
RequestPostProcessor {
private boolean asHeader;
private boolean useInvalidToken;
/*
* (non-Javadoc)
*
* @see
* org.springframework.test.web.servlet.request.RequestPostProcessor
* #postProcessRequest
* (org.springframework.mock.web.MockHttpServletRequest)
*/
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
CsrfTokenRepository repository = WebTestUtils
.getCsrfTokenRepository(request);
CsrfToken token = repository.generateToken(request);
repository.saveToken(token, request, new MockHttpServletResponse());
String tokenValue = useInvalidToken ? "invalid" + token.getToken() : token.getToken();
if(asHeader) {
request.addHeader(token.getHeaderName(), tokenValue);
} else {
request.setParameter(token.getParameterName(), tokenValue);
}
return request;
}
/**
* Instead of using the {@link CsrfToken} as a request parameter
* (default) will populate the {@link CsrfToken} as a header.
*
* @return the {@link CsrfRequestPostProcessor} for additional customizations
*/
public CsrfRequestPostProcessor asHeader() {
this.asHeader = true;
return this;
}
/**
* Populates an invalid token value on the request.
*
* @return the {@link CsrfRequestPostProcessor} for additional customizations
*/
public CsrfRequestPostProcessor useInvalidToken() {
this.useInvalidToken = true;
return this;
}
private CsrfRequestPostProcessor() {}
}
/**
* Support class for {@link RequestPostProcessor}'s that establish a Spring
* Security context
*/
private static abstract class SecurityContextRequestPostProcessorSupport {
/**
* Saves the specified {@link Authentication} into an empty
* {@link SecurityContext} using the {@link SecurityContextRepository}.
*
* @param authentication the {@link Authentication} to save
* @param request the {@link HttpServletRequest} to use
*/
final void save(Authentication authentication,
HttpServletRequest request) {
SecurityContext securityContext = SecurityContextHolder
.createEmptyContext();
securityContext.setAuthentication(authentication);
save(securityContext, request);
}
/**
* Saves the {@link SecurityContext} using the
* {@link SecurityContextRepository}
*
* @param securityContext the {@link SecurityContext} to save
* @param request the {@link HttpServletRequest} to use
*/
final void save(SecurityContext securityContext,
HttpServletRequest request) {
HttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(
request, response);
SecurityContextRepository securityContextRepository = WebTestUtils
.getSecurityContextRepository(request);
securityContextRepository.loadContext(requestResponseHolder);
request = requestResponseHolder.getRequest();
response = requestResponseHolder.getResponse();
securityContextRepository.saveContext(securityContext, request,
response);
}
}
/**
* Associates the {@link SecurityContext} found in
* {@link TestSecurityContextHolder#getContext()} with the
* {@link MockHttpServletRequest}.
*
* @author Rob Winch
* @since 4.0
*/
private final static class TestSecurityContextHolderPostProcessor extends
SecurityContextRequestPostProcessorSupport implements
RequestPostProcessor {
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
save(TestSecurityContextHolder.getContext(), request);
return request;
}
}
/**
* Associates the specified {@link SecurityContext} with the
* {@link MockHttpServletRequest}.
*
* @author Rob Winch
* @since 4.0
*/
private final static class SecurityContextRequestPostProcessor extends
SecurityContextRequestPostProcessorSupport implements
RequestPostProcessor {
private final SecurityContext securityContext;
private SecurityContextRequestPostProcessor(
SecurityContext securityContext) {
this.securityContext = securityContext;
}
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
save(this.securityContext, request);
return request;
}
}
/**
* Sets the specified {@link Authentication} on an empty
* {@link SecurityContext} and associates it to the
* {@link MockHttpServletRequest}
*
* @author Rob Winch
* @since 4.0
*
*/
private final static class AuthenticationRequestPostProcessor extends
SecurityContextRequestPostProcessorSupport implements
RequestPostProcessor {
private final Authentication authentication;
private AuthenticationRequestPostProcessor(Authentication authentication) {
this.authentication = authentication;
}
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(authentication);
save(authentication, request);
return request;
}
}
/**
* Creates a {@link UsernamePasswordAuthenticationToken} and sets the
* {@link UserDetails} as the principal and associates it to the
* {@link MockHttpServletRequest}.
*
* @author Rob Winch
* @since 4.0
*/
private final static class UserDetailsRequestPostProcessor implements
RequestPostProcessor {
private final RequestPostProcessor delegate;
public UserDetailsRequestPostProcessor(UserDetails user) {
Authentication token = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
delegate = new AuthenticationRequestPostProcessor(token);
}
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
return delegate.postProcessRequest(request);
}
}
/**
* Creates a {@link UsernamePasswordAuthenticationToken} and sets the
* principal to be a {@link User} and associates it to the
* {@link MockHttpServletRequest}.
*
* @author Rob Winch
* @since 4.0
*/
public final static class UserRequestPostProcessor extends
SecurityContextRequestPostProcessorSupport implements
RequestPostProcessor {
private String username;
private String password = "password";
private static final String ROLE_PREFIX = "ROLE_";
private Collection<? extends GrantedAuthority> authorities = AuthorityUtils
.createAuthorityList("ROLE_USER");
private boolean enabled = true;
private boolean accountNonExpired = true;
private boolean credentialsNonExpired = true;
private boolean accountNonLocked = true;
/**
* Creates a new instance with the given username
* @param username the username to use
*/
private UserRequestPostProcessor(String username) {
Assert.notNull(username, "username cannot be null");
this.username = username;
}
/**
* Specify the roles of the user to authenticate as. This method is
* similar to {@link #authorities(GrantedAuthority...)}, but just not as
* flexible.
*
* @param roles
* The roles to populate. Note that if the role does not
* start with {@link #rolePrefix(String)} it will
* automatically be prepended. This means by default
* {@code roles("ROLE_USER")} and {@code roles("USER")} are
* equivalent.
* @see #authorities(GrantedAuthority...)
* @see #rolePrefix(String)
* @return the UserRequestPostProcessor for further customizations
*/
public UserRequestPostProcessor roles(String... roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(
roles.length);
for (String role : roles) {
if (role.startsWith(ROLE_PREFIX)) {
throw new IllegalArgumentException("Role should not start with "+ROLE_PREFIX + " since this method automatically prefixes with this value. Got "+ role);
} else {
authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX
+ role));
}
}
this.authorities = authorities;
return this;
}
/**
* Populates the user's {@link GrantedAuthority}'s. The default is
* ROLE_USER.
*
* @param authorities
* @see #roles(String...)
* @return the UserRequestPostProcessor for further customizations
*/
public UserRequestPostProcessor authorities(
GrantedAuthority... authorities) {
return authorities(Arrays.asList(authorities));
}
/**
* Populates the user's {@link GrantedAuthority}'s. The default is
* ROLE_USER.
*
* @param authorities
* @see #roles(String...)
* @return the UserRequestPostProcessor for further customizations
*/
public UserRequestPostProcessor authorities(
Collection<? extends GrantedAuthority> authorities) {
this.authorities = authorities;
return this;
}
/**
* Populates the user's password. The default is "password"
*
* @param password
* the user's password
* @return the UserRequestPostProcessor for further customizations
*/
public UserRequestPostProcessor password(String password) {
this.password = password;
return this;
}
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
UserDetailsRequestPostProcessor delegate = new UserDetailsRequestPostProcessor(createUser());
return delegate.postProcessRequest(request);
}
/**
* Creates a new {@link User}
* @return the {@link User} for the principal
*/
private User createUser() {
return new User(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities);
}
}
private static class HttpBasicRequestPostProcessor implements RequestPostProcessor {
private String headerValue;
private HttpBasicRequestPostProcessor(String username, String password) {
byte[] toEncode;
try {
toEncode = (username + ":" + password).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
this.headerValue = "Basic " + new String(Base64.encode(toEncode));
}
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
request.addHeader("Authorization", headerValue);
return request;
}
}
private SecurityMockMvcRequestPostProcessors() { }
}

View File

@ -0,0 +1,226 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.response;
import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
/**
* Security related {@link MockMvc} {@link ResultMatcher}s.
*
* @author Rob Winch
* @since 4.0
*/
public final class SecurityMockMvcResultMatchers {
/**
* {@link ResultMatcher} that verifies that a specified user is
* authenticated.
*
* @return the {@link AuthenticatedMatcher} to use
*/
public static AuthenticatedMatcher authenticated() {
return new AuthenticatedMatcher();
}
/**
* {@link ResultMatcher} that verifies that no user is authenticated.
*
* @return the {@link AuthenticatedMatcher} to use
*/
public static ResultMatcher unauthenticated() {
return new UnAuthenticatedMatcher();
}
private static abstract class AuthenticationMatcher<T extends AuthenticationMatcher<T>> implements ResultMatcher {
protected SecurityContext load(MvcResult result) {
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(result.getRequest(), result.getResponse());
SecurityContextRepository repository = WebTestUtils.getSecurityContextRepository(result.getRequest());
return repository.loadContext(holder);
}
}
/**
* A {@link MockMvc} {@link ResultMatcher} that verifies a specific user is
* associated to the {@link MvcResult}.
*
* @author Rob Winch
* @since 4.0
*/
public static final class AuthenticatedMatcher extends AuthenticationMatcher<AuthenticatedMatcher> {
private SecurityContext expectedContext;
private Authentication expectedAuthentication;
private Object expectedAuthenticationPrincipal;
private String expectedAuthenticationName;
private Collection<GrantedAuthority> expectedGrantedAuthorities;
public void match(MvcResult result) throws Exception {
SecurityContext context = load(result);
Authentication auth = context.getAuthentication();
assertTrue("Authentication should not be null", auth != null);
if(this.expectedContext != null) {
assertEquals(this.expectedContext + " does not equal " + context, this.expectedContext, context);
}
if(this.expectedAuthentication != null) {
assertEquals(this.expectedAuthentication + " does not equal " + context.getAuthentication(), this.expectedAuthentication, context.getAuthentication());
}
if(this.expectedAuthenticationPrincipal != null) {
assertTrue("Authentication cannot be null", context.getAuthentication() != null);
assertEquals(this.expectedAuthenticationPrincipal + " does not equal " + context.getAuthentication().getPrincipal(), this.expectedAuthenticationPrincipal, context.getAuthentication().getPrincipal());
}
if(this.expectedAuthenticationName != null) {
assertTrue("Authentication cannot be null", auth != null);
String name = auth.getName();
assertEquals(this.expectedAuthenticationName + " does not equal " + name, this.expectedAuthenticationName, name);
}
if(this.expectedGrantedAuthorities != null) {
assertTrue("Authentication cannot be null", auth != null);
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
assertEquals(this.expectedGrantedAuthorities + " does not equal " + authorities, this.expectedGrantedAuthorities, authorities);
}
}
/**
* Specifies the expected username
*
* @param expected
* the expected username
* @return the {@link AuthenticatedMatcher} for further customization
*/
public AuthenticatedMatcher withUsername(String expected) {
return withAuthenticationName(expected);
}
/**
* Specifies the expected {@link SecurityContext}
*
* @param expected
* the expected {@link SecurityContext}
* @return the {@link AuthenticatedMatcher} for further customization
*/
public AuthenticatedMatcher withSecurityContext(SecurityContext expected) {
this.expectedContext = expected;
return this;
}
/**
* Specifies the expected {@link Authentication}
*
* @param expected
* the expected {@link Authentication}
* @return the {@link AuthenticatedMatcher} for further customization
*/
public AuthenticatedMatcher withAuthentication(Authentication expected) {
this.expectedAuthentication = expected;
return this;
}
/**
* Specifies the expected principal
*
* @param expected
* the expected principal
* @return the {@link AuthenticatedMatcher} for further customization
*/
public AuthenticatedMatcher withAuthenticationPrincipal(Object expected) {
this.expectedAuthenticationPrincipal = expected;
return this;
}
/**
* Specifies the expected {@link Authentication#getName()}
*
* @param expected
* the expected {@link Authentication#getName()}
* @return the {@link AuthenticatedMatcher} for further customization
*/
public AuthenticatedMatcher withAuthenticationName(String expected) {
this.expectedAuthenticationName = expected;
return this;
}
/**
* Specifies the {@link Authentication#getAuthorities()}
*
* @param expected the {@link Authentication#getAuthorities()}
* @return the {@link AuthenticatedMatcher} for further customization
*/
public AuthenticatedMatcher withAuthorities(Collection<GrantedAuthority> expected) {
this.expectedGrantedAuthorities = expected;
return this;
}
/**
* Specifies the {@link Authentication#getAuthorities()}
*
* @param expected the roles. Each value is automatically prefixed with "ROLE_"
* @return the {@link AuthenticatedMatcher} for further customization
*/
public AuthenticatedMatcher withRoles(String... roles) {
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for(String role : roles) {
authorities.add(new SimpleGrantedAuthority("ROLE_"+role));
}
return withAuthorities(authorities);
}
AuthenticatedMatcher() {}
}
/**
* A {@link MockMvc} {@link ResultMatcher} that verifies no
* {@link Authentication} is associated with the {@link MvcResult}.
*
* @author Rob Winch
* @since 4.0
*/
private static final class UnAuthenticatedMatcher extends AuthenticationMatcher<UnAuthenticatedMatcher>{
public void match(MvcResult result) throws Exception {
SecurityContext context = load(result);
assertEquals("",null,context.getAuthentication());
}
private UnAuthenticatedMatcher() {}
}
private SecurityMockMvcResultMatchers() {}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.support;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* A utility class for testing spring security
*
* @author Rob Winch
* @since 4.0
*/
public abstract class WebTestUtils {
private static final SecurityContextRepository DEFAULT_CONTEXT_REPO = new HttpSessionSecurityContextRepository();
private static final CsrfTokenRepository DEFAULT_TOKEN_REPO = new HttpSessionCsrfTokenRepository();
/**
* Gets the {@link SecurityContextRepository} for the specified
* {@link HttpServletRequest}. If one is not found, a default
* {@link HttpSessionSecurityContextRepository} is used.
*
* @param request
* the {@link HttpServletRequest} to obtain the
* {@link SecurityContextRepository}
* @return the {@link SecurityContextRepository} for the specified
* {@link HttpServletRequest}
*/
public static SecurityContextRepository getSecurityContextRepository(HttpServletRequest request) {
SecurityContextPersistenceFilter filter = findFilter(request, SecurityContextPersistenceFilter.class);
if(filter == null) {
return DEFAULT_CONTEXT_REPO;
}
return (SecurityContextRepository) ReflectionTestUtils.getField(filter, "repo");
}
/**
* Gets the {@link CsrfTokenRepository} for the specified
* {@link HttpServletRequest}. If one is not found, the default
* {@link HttpSessionCsrfTokenRepository} is used.
*
* @param request
* the {@link HttpServletRequest} to obtain the
* {@link CsrfTokenRepository}
* @return the {@link CsrfTokenRepository} for the specified
* {@link HttpServletRequest}
*/
public static CsrfTokenRepository getCsrfTokenRepository(HttpServletRequest request) {
CsrfFilter filter = findFilter(request, CsrfFilter.class);
if(filter == null) {
return DEFAULT_TOKEN_REPO;
}
return (CsrfTokenRepository) ReflectionTestUtils.getField(filter, "tokenRepository");
}
@SuppressWarnings("unchecked")
private static <T extends Filter> T findFilter(HttpServletRequest request, Class<T> filterClass) {
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
if(webApplicationContext == null) {
return null;
}
FilterChainProxy springSecurityFilterChain = null;
try {
springSecurityFilterChain = webApplicationContext.getBean(FilterChainProxy.class);
} catch(NoSuchBeanDefinitionException notFound) {
return null;
}
List<Filter> filters = (List<Filter>) ReflectionTestUtils.invokeMethod(springSecurityFilterChain,"getFilters", request);
for(Filter filter : filters) {
if(filterClass.isAssignableFrom(filter.getClass())) {
return (T) filter;
}
}
return null;
}
private WebTestUtils() {}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context;
import static org.fest.assertions.Assertions.assertThat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
public class TestSecurityContextHolderTests {
private SecurityContext context;
@Before
public void setup() {
context = SecurityContextHolder.createEmptyContext();
}
@After
public void cleanup() {
TestSecurityContextHolder.clearContext();
}
@Test
public void clearContextClearsBoth() {
SecurityContextHolder.setContext(context);
TestSecurityContextHolder.setContext(context);
TestSecurityContextHolder.clearContext();
assertThat(SecurityContextHolder.getContext()).isNotSameAs(context);
assertThat(TestSecurityContextHolder.getContext()).isNotSameAs(context);
}
@Test
public void getContextDefaultsNonNull() {
assertThat(TestSecurityContextHolder.getContext()).isNotNull();
assertThat(SecurityContextHolder.getContext()).isNotNull();
}
@Test
public void setContextSetsBoth() {
TestSecurityContextHolder.setContext(context);
assertThat(TestSecurityContextHolder.getContext()).isSameAs(context);
assertThat(SecurityContextHolder.getContext()).isSameAs(context);
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class WithMockUserSecurityContextFactoryTests {
@Mock
private WithMockUser withUser;
private WithMockUserSecurityContextFactory factory;
@Before
public void setup() {
factory = new WithMockUserSecurityContextFactory();
}
@Test(expected=IllegalArgumentException.class)
public void usernameNull() {
factory.createSecurityContext(withUser);
}
@Test
public void valueDefaultsUsername() {
when(withUser.value()).thenReturn("valueUser");
when(withUser.password()).thenReturn("password");
when(withUser.roles()).thenReturn(new String[] { "USER"});
assertThat(factory.createSecurityContext(withUser).getAuthentication().getName()).isEqualTo(withUser.value());
}
@Test
public void usernamePrioritizedOverValue() {
when(withUser.value()).thenReturn("valueUser");
when(withUser.username()).thenReturn("customUser");
when(withUser.password()).thenReturn("password");
when(withUser.roles()).thenReturn(new String[] { "USER"});
assertThat(factory.createSecurityContext(withUser).getAuthentication().getName()).isEqualTo(withUser.username());
}
@Test
public void rolesWorks() {
when(withUser.value()).thenReturn("valueUser");
when(withUser.password()).thenReturn("password");
when(withUser.roles()).thenReturn(new String[] { "USER", "CUSTOM"});
assertThat(factory.createSecurityContext(withUser).getAuthentication().getAuthorities()).onProperty("authority").containsOnly("ROLE_USER","ROLE_CUSTOM");
}
@Test(expected = IllegalArgumentException.class)
public void rolesWithRolePrefixFails() {
when(withUser.value()).thenReturn("valueUser");
when(withUser.password()).thenReturn("password");
when(withUser.roles()).thenReturn(new String[] { "ROLE_FAIL"});
factory.createSecurityContext(withUser);
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import static org.fest.assertions.Assertions.assertThat;
import org.junit.Test;
import org.springframework.core.annotation.AnnotationUtils;
public class WithMockUserTests {
@Test
public void defaults() {
WithMockUser mockUser = AnnotationUtils.findAnnotation(Annotated.class, WithMockUser.class);
assertThat(mockUser.value()).isEqualTo("user");
assertThat(mockUser.username()).isEmpty();
assertThat(mockUser.password()).isEqualTo("password");
assertThat(mockUser.roles()).containsOnly("USER");
}
@WithMockUser
private class Annotated {}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import static org.mockito.Mockito.when;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.test.context.TestContext;
import org.springframework.util.ReflectionUtils;
@RunWith(MockitoJUnitRunner.class)
public class WithSecurityContextTestExcecutionListenerTests {
private ConfigurableApplicationContext context;
@Mock
private TestContext testContext;
private WithSecurityContextTestExcecutionListener listener;
@Before
public void setup() {
listener = new WithSecurityContextTestExcecutionListener();
context = new AnnotationConfigApplicationContext(Config.class);
}
@After
public void cleanup() {
TestSecurityContextHolder.clearContext();
if(context != null) {
context.close();
}
}
@Test
@SuppressWarnings({ "rawtypes", "unchecked" })
public void beforeTestMethodNullSecurityContextNoError() throws Exception {
Class testClass = FakeTest.class;
when(testContext.getApplicationContext()).thenReturn(context);
when(testContext.getTestClass()).thenReturn(testClass);
when(testContext.getTestMethod()).thenReturn(ReflectionUtils.findMethod(testClass, "testNoAnnotation"));
listener.beforeTestMethod(testContext);
}
static class FakeTest {
public void testNoAnnotation() {}
}
@Configuration
static class Config {}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
@RunWith(MockitoJUnitRunner.class)
public class WithUserDetailsSecurityContextFactoryTests {
@Mock
private UserDetailsService userDetailsService;
@Mock
private UserDetails userDetails;
@Mock
private WithUserDetails withUserDetails;
private WithUserDetailsSecurityContextFactory factory;
@Before
public void setup() {
factory = new WithUserDetailsSecurityContextFactory(userDetailsService);
}
@Test(expected=IllegalArgumentException.class)
public void createSecurityContextNullValue() {
factory.createSecurityContext(withUserDetails);
}
@Test(expected=IllegalArgumentException.class)
public void createSecurityContextEmptyValue() {
when(withUserDetails.value()).thenReturn("");
factory.createSecurityContext(withUserDetails);
}
@Test
public void createSecurityContextWithExistingUser() {
String username = "user";
when(withUserDetails.value()).thenReturn(username);
when(userDetailsService.loadUserByUsername(username)).thenReturn(userDetails);
SecurityContext context = factory.createSecurityContext(withUserDetails);
assertThat(context.getAuthentication()).isInstanceOf(UsernamePasswordAuthenticationToken.class);
assertThat(context.getAuthentication().getPrincipal()).isEqualTo(userDetails);
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.context.support;
import static org.fest.assertions.Assertions.assertThat;
import org.junit.Test;
import org.springframework.core.annotation.AnnotationUtils;
public class WithUserDetailsTests {
@Test
public void defaults() {
WithUserDetails userDetails = AnnotationUtils.findAnnotation(Annotated.class, WithUserDetails.class);
assertThat(userDetails.value()).isEqualTo("user");
}
@WithUserDetails
private static class Annotated {}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.fest.assertions.Assertions.assertThat;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.DefaultCsrfToken;
@RunWith(PowerMockRunner.class)
@PrepareForTest({WebTestUtils.class,SecurityMockMvcRequestBuildersFormLoginTests.class})
public class SecurityMockMvcRequestBuildersFormLoginTests {
@Mock
private CsrfTokenRepository repository;
private DefaultCsrfToken token;
private MockServletContext servletContext;
@Before
public void setup() throws Exception {
token = new DefaultCsrfToken("header", "param", "token");
servletContext = new MockServletContext();
mockWebTestUtils();
}
@Test
public void defaults() throws Exception {
MockHttpServletRequest request = formLogin().buildRequest(servletContext);
assertThat(request.getParameter("username")).isEqualTo("user");
assertThat(request.getParameter("password")).isEqualTo("password");
assertThat(request.getMethod()).isEqualTo("POST");
assertThat(request.getParameter(token.getParameterName())).isEqualTo(token.getToken());
assertThat(request.getRequestURI()).isEqualTo("/login");
verify(repository).saveToken(eq(token), any(HttpServletRequest.class), any(HttpServletResponse.class));
}
@Test
public void custom() throws Exception {
MockHttpServletRequest request = formLogin("/j_spring_security_login")
.user("j_username","admin")
.password("j_password","secret")
.buildRequest(servletContext);
assertThat(request.getParameter("j_username")).isEqualTo("admin");
assertThat(request.getParameter("j_password")).isEqualTo("secret");
assertThat(request.getMethod()).isEqualTo("POST");
assertThat(request.getParameter(token.getParameterName())).isEqualTo(token.getToken());
assertThat(request.getRequestURI()).isEqualTo("/j_spring_security_login");
verify(repository).saveToken(eq(token), any(HttpServletRequest.class), any(HttpServletResponse.class));
}
private void mockWebTestUtils() throws Exception {
spy(WebTestUtils.class);
doReturn(repository).when(WebTestUtils.class,"getCsrfTokenRepository",any(HttpServletRequest.class));
when(repository.generateToken(any(HttpServletRequest.class))).thenReturn(token);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.fest.assertions.Assertions.assertThat;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.logout;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.DefaultCsrfToken;
@RunWith(PowerMockRunner.class)
@PrepareForTest({WebTestUtils.class,SecurityMockMvcRequestBuildersFormLogoutTests.class})
public class SecurityMockMvcRequestBuildersFormLogoutTests {
@Mock
private CsrfTokenRepository repository;
private DefaultCsrfToken token;
private MockServletContext servletContext;
@Before
public void setup() {
token = new DefaultCsrfToken("header", "param", "token");
servletContext = new MockServletContext();
}
@Test
public void defaults() throws Exception {
mockWebTestUtils();
MockHttpServletRequest request = logout().buildRequest(servletContext);
assertThat(request.getMethod()).isEqualTo("POST");
assertThat(request.getParameter(token.getParameterName())).isEqualTo(token.getToken());
assertThat(request.getRequestURI()).isEqualTo("/logout");
verify(repository).saveToken(eq(token), any(HttpServletRequest.class), any(HttpServletResponse.class));
}
@Test
public void custom() throws Exception {
mockWebTestUtils();
MockHttpServletRequest request = logout("/admin/logout").buildRequest(servletContext);
assertThat(request.getMethod()).isEqualTo("POST");
assertThat(request.getParameter(token.getParameterName())).isEqualTo(token.getToken());
assertThat(request.getRequestURI()).isEqualTo("/admin/logout");
verify(repository).saveToken(eq(token), any(HttpServletRequest.class), any(HttpServletResponse.class));
}
private void mockWebTestUtils() throws Exception {
spy(WebTestUtils.class);
doReturn(repository).when(WebTestUtils.class,"getCsrfTokenRepository",any(HttpServletRequest.class));
when(repository.generateToken(any(HttpServletRequest.class))).thenReturn(token);
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.context.SecurityContextRepository;
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest(WebTestUtils.class)
public class SecurityMockMvcRequestPostProcessorsAuthenticationTests {
@Captor
private ArgumentCaptor<SecurityContext> contextCaptor;
@Mock
private SecurityContextRepository repository;
private MockHttpServletRequest request;
@Mock
private Authentication authentication;
@Before
public void setup() {
request = new MockHttpServletRequest();
mockWebTestUtils();
}
@After
public void cleanup() {
TestSecurityContextHolder.clearContext();
}
@Test
public void userDetails() {
authentication(authentication).postProcessRequest(request);
verify(repository).saveContext(contextCaptor.capture(), eq(request), any(HttpServletResponse.class));
SecurityContext context = contextCaptor.getValue();
assertThat(context.getAuthentication()).isSameAs(authentication);
}
private void mockWebTestUtils() {
spy(WebTestUtils.class);
when(WebTestUtils.getSecurityContextRepository(request)).thenReturn(repository);
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.fest.assertions.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.powermock.api.mockito.PowerMockito.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.DefaultCsrfToken;
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest(WebTestUtils.class)
public class SecurityMockMvcRequestPostProcessorsCsrfTests {
@Mock
private CsrfTokenRepository repository;
private DefaultCsrfToken token;
private MockHttpServletRequest request;
@Before
public void setup() {
token = new DefaultCsrfToken("header", "param", "token");
request = new MockHttpServletRequest();
mockWebTestUtils();
}
@Test
public void csrfWithParam() {
MockHttpServletRequest postProcessedRequest = csrf().postProcessRequest(request);
assertThat(postProcessedRequest.getParameter(token.getParameterName())).isEqualTo(token.getToken());
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isNull();
}
@Test
public void csrfWithHeader() {
MockHttpServletRequest postProcessedRequest = csrf().asHeader().postProcessRequest(request);
assertThat(postProcessedRequest.getParameter(token.getParameterName())).isNull();
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isEqualTo(token.getToken());
}
@Test
public void csrfWithInvalidParam() {
MockHttpServletRequest postProcessedRequest = csrf().useInvalidToken().postProcessRequest(request);
assertThat(postProcessedRequest.getParameter(token.getParameterName())).isNotEmpty().isNotEqualTo(token.getToken());
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isNull();
}
@Test
public void csrfWithInvalidHeader() {
MockHttpServletRequest postProcessedRequest = csrf().asHeader().useInvalidToken().postProcessRequest(request);
assertThat(postProcessedRequest.getParameter(token.getParameterName())).isNull();
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isNotEmpty().isNotEqualTo(token.getToken());
}
private void mockWebTestUtils() {
spy(WebTestUtils.class);
when(WebTestUtils.getCsrfTokenRepository(request)).thenReturn(repository);
when(repository.loadToken(request)).thenReturn(token);
when(repository.generateToken(request)).thenReturn(token);
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.securityContext;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.context.SecurityContextRepository;
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest(WebTestUtils.class)
public class SecurityMockMvcRequestPostProcessorsSecurityContextTests {
@Captor
private ArgumentCaptor<SecurityContext> contextCaptor;
@Mock
private SecurityContextRepository repository;
private MockHttpServletRequest request;
@Mock
private SecurityContext expectedContext;
@Before
public void setup() {
request = new MockHttpServletRequest();
mockWebTestUtils();
}
@After
public void cleanup() {
TestSecurityContextHolder.clearContext();
}
@Test
public void userDetails() {
securityContext(expectedContext).postProcessRequest(request);
verify(repository).saveContext(contextCaptor.capture(), eq(request), any(HttpServletResponse.class));
SecurityContext context = contextCaptor.getValue();
assertThat(context).isSameAs(this.expectedContext);
}
private void mockWebTestUtils() {
spy(WebTestUtils.class);
when(WebTestUtils.getSecurityContextRepository(request)).thenReturn(repository);
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.powermock.api.mockito.PowerMockito.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.any;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.testSecurityContext;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.context.SecurityContextRepository;
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest(WebTestUtils.class)
public class SecurityMockMvcRequestPostProcessorsTestSecurityContextTests {
@Mock
private SecurityContext context;
@Mock
private SecurityContextRepository repository;
private MockHttpServletRequest request;
@Before
public void setup() {
request = new MockHttpServletRequest();
mockWebTestUtils();
}
@After
public void cleanup() {
TestSecurityContextHolder.clearContext();
}
@Test
public void testSecurityContextSaves() {
TestSecurityContextHolder.setContext(context);
testSecurityContext().postProcessRequest(request);
verify(repository).saveContext(eq(context), eq(request), any(HttpServletResponse.class));
}
// Ensure it does not fail if TestSecurityContextHolder is not initialized
@Test
public void testSecurityContextNoContext() {
testSecurityContext().postProcessRequest(request);
verify(repository).saveContext(any(SecurityContext.class), eq(request), any(HttpServletResponse.class));
}
private void mockWebTestUtils() {
spy(WebTestUtils.class);
when(WebTestUtils.getSecurityContextRepository(request)).thenReturn(repository);
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.context.SecurityContextRepository;
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest(WebTestUtils.class)
public class SecurityMockMvcRequestPostProcessorsUserDetailsTests {
@Captor
private ArgumentCaptor<SecurityContext> contextCaptor;
@Mock
private SecurityContextRepository repository;
private MockHttpServletRequest request;
@Mock
private UserDetails userDetails;
@Before
public void setup() {
request = new MockHttpServletRequest();
mockWebTestUtils();
}
@After
public void cleanup() {
TestSecurityContextHolder.clearContext();
}
@Test
public void userDetails() {
user(userDetails).postProcessRequest(request);
verify(repository).saveContext(contextCaptor.capture(), eq(request), any(HttpServletResponse.class));
SecurityContext context = contextCaptor.getValue();
assertThat(context.getAuthentication()).isInstanceOf(UsernamePasswordAuthenticationToken.class);
assertThat(context.getAuthentication().getPrincipal()).isSameAs(userDetails);
}
private void mockWebTestUtils() {
spy(WebTestUtils.class);
when(WebTestUtils.getSecurityContextRepository(request)).thenReturn(repository);
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.request;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import java.util.Arrays;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.security.test.web.support.WebTestUtils;
import org.springframework.security.web.context.SecurityContextRepository;
@RunWith(PowerMockRunner.class)
@PrepareOnlyThisForTest(WebTestUtils.class)
public class SecurityMockMvcRequestPostProcessorsUserTests {
@Captor
private ArgumentCaptor<SecurityContext> contextCaptor;
@Mock
private SecurityContextRepository repository;
private MockHttpServletRequest request;
@Mock
private GrantedAuthority authority1;
@Mock
private GrantedAuthority authority2;
@Before
public void setup() {
request = new MockHttpServletRequest();
mockWebTestUtils();
}
@After
public void cleanup() {
TestSecurityContextHolder.clearContext();
}
@Test
public void userWithDefaults() {
String username = "userabc";
user(username).postProcessRequest(request);
verify(repository).saveContext(contextCaptor.capture(), eq(request), any(HttpServletResponse.class));
SecurityContext context = contextCaptor.getValue();
assertThat(context.getAuthentication()).isInstanceOf(UsernamePasswordAuthenticationToken.class);
assertThat(context.getAuthentication().getName()).isEqualTo(username);
assertThat(context.getAuthentication().getCredentials()).isEqualTo("password");
assertThat(context.getAuthentication().getAuthorities()).onProperty("authority").containsOnly("ROLE_USER");
}
@Test
public void userWithCustom() {
String username = "customuser";
user(username)
.roles("CUSTOM","ADMIN")
.password("newpass")
.postProcessRequest(request);
verify(repository).saveContext(contextCaptor.capture(), eq(request), any(HttpServletResponse.class));
SecurityContext context = contextCaptor.getValue();
assertThat(context.getAuthentication()).isInstanceOf(UsernamePasswordAuthenticationToken.class);
assertThat(context.getAuthentication().getName()).isEqualTo(username);
assertThat(context.getAuthentication().getCredentials()).isEqualTo("newpass");
assertThat(context.getAuthentication().getAuthorities()).onProperty("authority").containsOnly("ROLE_CUSTOM","ROLE_ADMIN");
}
@Test
public void userCustomAuthoritiesVarargs() {
String username = "customuser";
user(username)
.authorities(authority1,authority2)
.postProcessRequest(request);
verify(repository).saveContext(contextCaptor.capture(), eq(request), any(HttpServletResponse.class));
SecurityContext context = contextCaptor.getValue();
assertThat(context.getAuthentication().getAuthorities()).containsOnly(authority1,authority2);
}
@Test(expected = IllegalArgumentException.class)
public void userRolesWithRolePrefixErrors() {
user("user")
.roles("ROLE_INVALID")
.postProcessRequest(request);
}
@Test
public void userCustomAuthoritiesList() {
String username = "customuser";
user(username)
.authorities(Arrays.asList(authority1,authority2))
.postProcessRequest(request);
verify(repository).saveContext(contextCaptor.capture(), eq(request), any(HttpServletResponse.class));
SecurityContext context = contextCaptor.getValue();
assertThat(context.getAuthentication().getAuthorities()).containsOnly(authority1,authority2);
}
private void mockWebTestUtils() {
spy(WebTestUtils.class);
when(WebTestUtils.getSecurityContextRepository(request)).thenReturn(repository);
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CsrfShowcaseTests.Config.class)
@WebAppConfiguration
public class CsrfShowcaseTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void postWithCsrfWorks() throws Exception {
mvc
.perform(post("/").with(csrf()))
.andExpect(status().isNotFound());
}
@Test
public void postWithCsrfWorksWithPut() throws Exception {
mvc
.perform(put("/").with(csrf()))
.andExpect(status().isNotFound());
}
@Test
public void postWithNoCsrfForbidden() throws Exception {
mvc
.perform(post("/"))
.andExpect(status().isForbidden());
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CustomCsrfShowcaseTests.Config.class)
@WebAppConfiguration
public class CustomCsrfShowcaseTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
@Autowired
private CsrfTokenRepository repository;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest(get("/").with(csrf()))
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void postWithCsrfWorks() throws Exception {
mvc
.perform(post("/").with(csrf()))
.andExpect(status().isNotFound());
}
@Test
public void postWithCsrfWorksWithPut() throws Exception {
mvc
.perform(put("/").with(csrf()))
.andExpect(status().isNotFound());
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(repo());
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Bean
public CsrfTokenRepository repo() {
HttpSessionCsrfTokenRepository repo = new HttpSessionCsrfTokenRepository();
repo.setParameterName("custom_csrf");
return repo;
}
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=DefaultCsrfShowcaseTests.Config.class)
@WebAppConfiguration
public class DefaultCsrfShowcaseTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest(get("/").with(csrf()))
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void postWithCsrfWorks() throws Exception {
mvc
.perform(post("/"))
.andExpect(status().isNotFound());
}
@Test
public void postWithCsrfWorksWithPut() throws Exception {
mvc
.perform(put("/"))
.andExpect(status().isNotFound());
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.login;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=AuthenticationTests.Config.class)
@WebAppConfiguration
public class AuthenticationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void requiresAuthentication() throws Exception {
mvc
.perform(get("/"))
.andExpect(status().isMovedTemporarily());
}
@Test
public void httpBasicAuthenticationSuccess() throws Exception {
mvc
.perform(get("/secured/butnotfound").with(httpBasic("user","password")))
.andExpect(status().isNotFound())
.andExpect(authenticated().withUsername("user"));
}
@Test
public void authenticationSuccess() throws Exception {
mvc
.perform(formLogin())
.andExpect(status().isMovedTemporarily())
.andExpect(redirectedUrl("/"))
.andExpect(authenticated().withUsername("user"));
}
@Test
public void authenticationFailed() throws Exception {
mvc
.perform(formLogin().user("user").password("invalid"))
.andExpect(status().isMovedTemporarily())
.andExpect(redirectedUrl("/login?error"))
.andExpect(unauthenticated());
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.login;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CustomConfigAuthenticationTests.Config.class)
@WebAppConfiguration
public class CustomConfigAuthenticationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
@Autowired
private SecurityContextRepository securityContextRepository;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest(get("/"))
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void authenticationSuccess() throws Exception {
mvc
.perform(formLogin("/authenticate").user("user","user").password("pass","password"))
.andExpect(status().isMovedTemporarily())
.andExpect(redirectedUrl("/"))
.andExpect(authenticated().withUsername("user"));
}
@Test
public void withUserSuccess() throws Exception {
mvc
.perform(get("/").with(user("user")))
.andExpect(status().isNotFound())
.andExpect(authenticated().withUsername("user"));
}
@Test
public void authenticationFailed() throws Exception {
mvc
.perform(formLogin("/authenticate").user("user","notfound").password("pass","invalid"))
.andExpect(status().isMovedTemporarily())
.andExpect(redirectedUrl("/authenticate?error"))
.andExpect(unauthenticated());
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.securityContext()
.securityContextRepository(securityContextRepository())
.and()
.formLogin()
.usernameParameter("user")
.passwordParameter("pass")
.loginPage("/authenticate");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Bean
public SecurityContextRepository securityContextRepository() {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
repo.setSpringSecurityContextKey("CUSTOM");
return repo;
}
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.login;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders;
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.FormLoginRequestBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CustomLoginRequestBuilderAuthenticationTests.Config.class)
@WebAppConfiguration
public class CustomLoginRequestBuilderAuthenticationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void authenticationSuccess() throws Exception {
mvc
.perform(login())
.andExpect(status().isMovedTemporarily())
.andExpect(redirectedUrl("/"))
.andExpect(authenticated().withUsername("user"));
}
@Test
public void authenticationFailed() throws Exception {
mvc
.perform(login().user("notfound").password("invalid"))
.andExpect(status().isMovedTemporarily())
.andExpect(redirectedUrl("/authenticate?error"))
.andExpect(unauthenticated());
}
static FormLoginRequestBuilder login() {
return SecurityMockMvcRequestBuilders
.formLogin("/authenticate")
.userParameter("user")
.passwordParam("pass");
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.usernameParameter("user")
.passwordParameter("pass")
.loginPage("/authenticate");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.secured;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=DefaultfSecurityRequestsTests.Config.class)
@WebAppConfiguration
public class DefaultfSecurityRequestsTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest(get("/").with(user("user").roles("ADMIN")))
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user"));
}
@Test
public void requestProtectedUrlWithAdmin() throws Exception {
mvc
.perform(get("/admin"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user"));
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}

View File

@ -0,0 +1,141 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.secured;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=SecurityRequestsTests.Config.class)
@WebAppConfiguration
public class SecurityRequestsTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
@Autowired
private UserDetailsService userDetailsService;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
@Test
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/").with(user("user")))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user"));
}
@Test
public void requestProtectedUrlWithAdmin() throws Exception {
mvc
.perform(get("/admin").with(user("admin").roles("ADMIN")))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with admin
.andExpect(authenticated().withUsername("admin"));
}
@Test
public void requestProtectedUrlWithUserDetails() throws Exception {
UserDetails user = userDetailsService.loadUserByUsername("user");
mvc
.perform(get("/").with(user(user)))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withAuthenticationPrincipal(user));
}
@Test
public void requestProtectedUrlWithAuthentication() throws Exception {
Authentication authentication = new TestingAuthenticationToken("test", "notused", "ROLE_USER");
mvc
.perform(get("/").with(authentication(authentication)))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withAuthentication(authentication));
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.secured;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.test.context.support.WithSecurityContextTestExcecutionListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.test.context.web.ServletTestExecutionListener;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=WithUserAuthenticationTests.Config.class)
@WebAppConfiguration
@TestExecutionListeners(listeners={ServletTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
WithSecurityContextTestExcecutionListener.class})
public class WithUserAuthenticationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.defaultRequest(get("/").with(testSecurityContext()))
.build();
}
@Test
@WithMockUser
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user"));
}
@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithAdmin() throws Exception {
mvc
.perform(get("/admin"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user").withRoles("ADMIN"));
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}

View File

@ -0,0 +1,119 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.secured;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.test.context.support.WithSecurityContextTestExcecutionListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.test.context.web.ServletTestExecutionListener;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=WithUserClassLevelAuthenticationTests.Config.class)
@WebAppConfiguration
@TestExecutionListeners(listeners={ServletTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
WithSecurityContextTestExcecutionListener.class})
@WithMockUser(roles="ADMIN")
public class WithUserClassLevelAuthenticationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.defaultRequest(get("/").with(testSecurityContext()))
.build();
}
@Test
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user"));
}
@Test
public void requestProtectedUrlWithAdmin() throws Exception {
mvc
.perform(get("/admin"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user").withRoles("ADMIN"));
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.secured;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.testSecurityContext;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.security.test.context.support.WithSecurityContextTestExcecutionListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.test.context.web.ServletTestExecutionListener;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=WithUserDetailsAuthenticationTests.Config.class)
@WebAppConfiguration
@TestExecutionListeners(listeners={ServletTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
WithSecurityContextTestExcecutionListener.class})
public class WithUserDetailsAuthenticationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.defaultRequest(get("/").with(testSecurityContext()))
.build();
}
@Test
@WithUserDetails
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("user"));
}
@Test
@WithUserDetails("admin")
public void requestProtectedUrlWithAdmin() throws Exception {
mvc
.perform(get("/admin"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("admin").withRoles("ADMIN","USER"));
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER","ADMIN");
}
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.servlet.showcase.secured;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.testSecurityContext;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import javax.servlet.Filter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.security.test.context.support.WithSecurityContextTestExcecutionListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.test.context.web.ServletTestExecutionListener;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=WithUserDetailsClassLevelAuthenticationTests.Config.class)
@WebAppConfiguration
@TestExecutionListeners(listeners={ServletTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
WithSecurityContextTestExcecutionListener.class})
@WithUserDetails("admin")
public class WithUserDetailsClassLevelAuthenticationTests {
@Autowired
private WebApplicationContext context;
@Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.defaultRequest(get("/").with(testSecurityContext()))
.build();
}
@Test
public void requestRootUrlWithAdmin() throws Exception {
mvc
.perform(get("/"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("admin").withRoles("ADMIN","USER"));
}
@Test
public void requestProtectedUrlWithAdmin() throws Exception {
mvc
.perform(get("/admin"))
// Ensure we got past Security
.andExpect(status().isNotFound())
// Ensure it appears we are authenticated with user
.andExpect(authenticated().withUsername("admin").withRoles("ADMIN","USER"));
}
@Configuration
@EnableWebMvcSecurity
@EnableWebMvc
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER","ADMIN");
}
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.test.web.support;
import static org.fest.assertions.Assertions.assertThat;
import static org.springframework.security.test.web.support.WebTestUtils.getCsrfTokenRepository;
import static org.springframework.security.test.web.support.WebTestUtils.getSecurityContextRepository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
@RunWith(MockitoJUnitRunner.class)
public class WebTestUtilsTests {
@Mock
private SecurityContextRepository contextRepo;
@Mock
private CsrfTokenRepository csrfRepo;
private MockHttpServletRequest request;
private ConfigurableApplicationContext context;
@Before
public void setup() {
request = new MockHttpServletRequest();
}
@After
public void cleanup() {
if(context != null) {
context.close();
}
}
@Test
public void getCsrfTokenRepositorytNoWac() {
assertThat(getCsrfTokenRepository(request)).isInstanceOf(HttpSessionCsrfTokenRepository.class);
}
@Test
public void getCsrfTokenRepositorytNoSecurity() {
loadConfig(Config.class);
assertThat(getCsrfTokenRepository(request)).isInstanceOf(HttpSessionCsrfTokenRepository.class);
}
@Test
public void getCsrfTokenRepositorytSecurityNoCsrf() {
loadConfig(SecurityNoCsrfConfig.class);
assertThat(getCsrfTokenRepository(request)).isInstanceOf(HttpSessionCsrfTokenRepository.class);
}
@Test
public void getCsrfTokenRepositorytSecurityCustomRepo() {
CustomSecurityConfig.CONTEXT_REPO = contextRepo;
CustomSecurityConfig.CSRF_REPO = csrfRepo;
loadConfig(CustomSecurityConfig.class);
assertThat(getCsrfTokenRepository(request)).isSameAs(csrfRepo);
}
// getSecurityContextRepository
@Test
public void getSecurityContextRepositoryNoWac() {
assertThat(getSecurityContextRepository(request)).isInstanceOf(HttpSessionSecurityContextRepository.class);
}
@Test
public void getSecurityContextRepositoryNoSecurity() {
loadConfig(Config.class);
assertThat(getSecurityContextRepository(request)).isInstanceOf(HttpSessionSecurityContextRepository.class);
}
@Test
public void getSecurityContextRepositorySecurityNoCsrf() {
loadConfig(SecurityNoCsrfConfig.class);
assertThat(getSecurityContextRepository(request)).isInstanceOf(HttpSessionSecurityContextRepository.class);
}
@Test
public void getSecurityContextRepositorySecurityCustomRepo() {
CustomSecurityConfig.CONTEXT_REPO = contextRepo;
CustomSecurityConfig.CSRF_REPO = csrfRepo;
loadConfig(CustomSecurityConfig.class);
assertThat(getSecurityContextRepository(request)).isSameAs(contextRepo);
}
private void loadConfig(Class<?> config) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(config);
context.refresh();
this.context = context;
request.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
}
@Configuration
static class Config {}
@Configuration
@EnableWebSecurity
static class SecurityNoCsrfConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
@Configuration
@EnableWebSecurity
static class CustomSecurityConfig extends WebSecurityConfigurerAdapter {
static CsrfTokenRepository CSRF_REPO;
static SecurityContextRepository CONTEXT_REPO;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CSRF_REPO)
.and()
.securityContext()
.securityContextRepository(CONTEXT_REPO);
}
}
}

18
test/template.mf Normal file
View File

@ -0,0 +1,18 @@
Implementation-Title: org.springframework.security.test
Implementation-Version: ${version}
Bundle-SymbolicName: org.springframework.security.test
Bundle-Name: Spring Security Test
Bundle-Vendor: SpringSource
Bundle-Version: ${version}
Bundle-ManifestVersion: 2
Ignored-Existing-Headers:
Import-Package,
Export-Package
Import-Template:
org.apache.commons.logging.*;version="${cloggingRange}",
org.springframework.security.core.*;version="${secRange}",
org.springframework.security.authentication.*;version="${secRange}",
org.springframework.security.web.*;version="${secRange}",
org.springframework.beans.factory;version="${springRange}",
org.springframework.util;version="${springRange}",
javax.servlet.*;version="0"

13
test/test.gradle Normal file
View File

@ -0,0 +1,13 @@
// OpenID Module build file
dependencies {
compile project(':spring-security-core'),
project(':spring-security-web'),
"org.springframework:spring-test:$springVersion"
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
testCompile project(':spring-security-config'),
"org.springframework:spring-webmvc:$springVersion",
powerMockDependencies
}

View File

@ -0,0 +1,108 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.savedrequest;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.Assert;
public class RequestCacheAdapter implements RequestCache {
private final RequestCache delegate;
public RequestCacheAdapter() {
this(new HttpSessionRequestCache());
}
public RequestCacheAdapter(RequestCache delegate) {
Assert.notNull(delegate, "delegate cannot be null");
this.delegate = delegate;
}
public void saveRequest(HttpServletRequest request,
HttpServletResponse response) {
delegate.saveRequest(request, response);
}
public SavedRequest getRequest(HttpServletRequest request,
HttpServletResponse response) {
SavedRequest result = delegate.getRequest(request, response);
Cookie[] cookies = request.getCookies();
return new SavedRequestAdapter(result, cookies == null ? null : Arrays.asList(cookies));
}
public HttpServletRequest getMatchingRequest(HttpServletRequest request,
HttpServletResponse response) {
return delegate.getMatchingRequest(request, response);
}
public void removeRequest(HttpServletRequest request,
HttpServletResponse response) {
delegate.removeRequest(request, response);
}
private static class SavedRequestAdapter implements SavedRequest {
private SavedRequest delegate;
private List<Cookie> cookies;
public SavedRequestAdapter(SavedRequest delegate, List<Cookie> cookies) {
this.delegate = delegate;
this.cookies = cookies;
}
public String getRedirectUrl() {
return delegate.getRedirectUrl();
}
public List<Cookie> getCookies() {
return cookies;
}
public String getMethod() {
return delegate.getMethod();
}
public List<String> getHeaderValues(String name) {
return delegate.getHeaderValues(name);
}
public Collection<String> getHeaderNames() {
return delegate.getHeaderNames();
}
public List<Locale> getLocales() {
return delegate.getLocales();
}
public String[] getParameterValues(String name) {
return delegate.getParameterValues(name);
}
public Map<String, String[]> getParameterMap() {
return delegate.getParameterMap();
}
private static final long serialVersionUID = 1184951442151447331L;
}
}