mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-02-24 07:37:50 +00:00
SEC-3074: Add Test Meta Annotation Support
This commit is contained in:
parent
55dd247660
commit
567c51e109
@ -249,6 +249,33 @@ final class WithUserDetailsSecurityContextFactory
|
||||
}
|
||||
----
|
||||
|
||||
[[test-method-meta-annotations]]
|
||||
=== Test Meta Annotations
|
||||
|
||||
If you reuse the same user within your tests often, it is not ideal to have to repeatedly specify the attributes.
|
||||
For example, if there are many tests related to an administrative user with the username "admin" and the roles `ROLE_USER` and `ROLE_ADMIN` you would have to write:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@WithMockUser(username="admin",roles={"USER","ADMIN"})
|
||||
----
|
||||
|
||||
Rather than repeating this everywhere, we can use a meta annotation.
|
||||
For example, we could create a meta annotation named `WithMockAdmin`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@WithMockUser(value="rob",roles="ADMIN")
|
||||
public @interface WithMockAdmin { }
|
||||
----
|
||||
|
||||
Now we can use `@WithMockAdmin` in the same way as the more verbose `@WithMockUser`.
|
||||
|
||||
Meta annotations work with any of the testing annotations described above.
|
||||
For example, this means we could create a meta annotation for `@WithUserDetails("admin")` as well.
|
||||
|
||||
|
||||
[[test-mockmvc]]
|
||||
== Spring MVC Test Integration
|
||||
|
||||
|
@ -367,7 +367,11 @@ git clone https://github.com/spring-projects/spring-security.git
|
||||
This will give you access to the entire project history (including all releases and branches) on your local machine.
|
||||
|
||||
[[new]]
|
||||
== What's new in Spring Security 4.0
|
||||
== What's new in Spring Security 4.1
|
||||
|
||||
* <<test-method-meta-annotations>>
|
||||
|
||||
=== What's new in Spring Security 4.0
|
||||
|
||||
There are http://goo.gl/ui9GCl[175+ tickets resolved] with the Spring Security 4.0 release.
|
||||
|
||||
|
@ -16,10 +16,13 @@
|
||||
package org.springframework.security.test.context.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
@ -59,13 +62,10 @@ public class WithSecurityContextTestExecutionListener extends
|
||||
*/
|
||||
@Override
|
||||
public void beforeTestMethod(TestContext testContext) throws Exception {
|
||||
Annotation[] methodAnnotations = AnnotationUtils.getAnnotations(testContext
|
||||
.getTestMethod());
|
||||
SecurityContext securityContext = createSecurityContext(methodAnnotations,
|
||||
SecurityContext securityContext = createSecurityContext(testContext.getTestMethod(),
|
||||
testContext);
|
||||
if (securityContext == null) {
|
||||
Annotation[] classAnnotations = testContext.getTestClass().getAnnotations();
|
||||
securityContext = createSecurityContext(classAnnotations, testContext);
|
||||
securityContext = createSecurityContext(testContext.getTestClass(), testContext);
|
||||
}
|
||||
if (securityContext != null) {
|
||||
TestSecurityContextHolder.setContext(securityContext);
|
||||
@ -73,20 +73,20 @@ public class WithSecurityContextTestExecutionListener extends
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private SecurityContext createSecurityContext(Annotation[] annotations,
|
||||
private SecurityContext createSecurityContext(AnnotatedElement annotated,
|
||||
TestContext 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);
|
||||
}
|
||||
WithSecurityContext withUser = AnnotationUtils.findAnnotation(
|
||||
annotated, WithSecurityContext.class);
|
||||
if (withUser != null) {
|
||||
WithSecurityContextFactory factory = createFactory(withUser, context);
|
||||
Class<? extends Annotation> type = (Class<? extends Annotation>) GenericTypeResolver.resolveTypeArgument(factory.getClass(), WithSecurityContextFactory.class);
|
||||
Annotation annotation = AnnotationUtils.findAnnotation(annotated, type);
|
||||
try {
|
||||
return factory.createSecurityContext(annotation);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to create SecurityContext using " + annotation, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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 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.test.context.support.WithMockUser;
|
||||
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
@WithMockUser(value="rob",roles="ADMIN")
|
||||
public @interface WithAdminRob {
|
||||
}
|
@ -64,6 +64,16 @@ public class WithUserAuthenticationTests {
|
||||
.andExpect(authenticated().withUsername("user"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithAdminRob
|
||||
public void requestProtectedUrlWithAdminRob() throws Exception {
|
||||
mvc.perform(get("/"))
|
||||
// Ensure we got past Security
|
||||
.andExpect(status().isNotFound())
|
||||
// Ensure it appears we are authenticated with user
|
||||
.andExpect(authenticated().withUsername("rob").withRoles("ADMIN"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(roles = "ADMIN")
|
||||
public void requestProtectedUrlWithAdmin() throws Exception {
|
||||
|
Loading…
x
Reference in New Issue
Block a user