瀏覽代碼

SEC-2984: Add @WithMockUser authorities property

Rob Winch 10 年之前
父節點
當前提交
e4517016ca

+ 19 - 0
test/src/main/java/org/springframework/security/test/context/support/WithMockUser.java

@@ -70,14 +70,33 @@ public @interface WithMockUser {
 	String username() default "";
 
 	/**
+	 * <p>
 	 * 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.
+	 * </p>
+	 * <p>
+	 * If {@link #authorities()} is specified this property cannot be changed from the default.
+	 * </p>
 	 *
 	 * @return
 	 */
 	String[] roles() default { "USER" };
 
+	/**
+	 * <p>
+	 * The authorities to use. A {@link GrantedAuthority} will be created for each value.
+	 * </p>
+	 *
+	 * <p>
+	 * If this property is specified then {@link #roles()} is not used. This differs from
+	 * {@link #roles()} in that it does not prefix the values passed in automatically.
+	 * </p>
+	 *
+	 * @return
+	 */
+	String[] authorities() default {};
+
 	/**
 	 * The password to be used. The default is "password".
 	 * @return

+ 18 - 7
test/src/main/java/org/springframework/security/test/context/support/WithMockUserSecurityContextFactory.java

@@ -16,6 +16,7 @@
 package org.springframework.security.test.context.support;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -44,16 +45,26 @@ final class WithMockUserSecurityContextFactory implements
 			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);
+
+		List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
+		for (String authority : withUser.authorities()) {
+			grantedAuthorities.add(new SimpleGrantedAuthority(authority));
+		}
+
+		if(grantedAuthorities.isEmpty()) {
+			for (String role : withUser.roles()) {
+				if (role.startsWith("ROLE_")) {
+					throw new IllegalArgumentException("roles cannot start with ROLE_ Got "
+							+ role);
+				}
+				grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role));
 			}
-			authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
+		} else if(!(withUser.roles().length == 1 && "USER".equals(withUser.roles()[0]))) {
+			throw new IllegalStateException("You cannot define roles attribute "+ Arrays.asList(withUser.roles())+" with authorities attribute "+ Arrays.asList(withUser.authorities()));
 		}
+
 		User principal = new User(username, withUser.password(), true, true, true, true,
-				authorities);
+				grantedAuthorities);
 		Authentication authentication = new UsernamePasswordAuthenticationToken(
 				principal, principal.getPassword(), principal.getAuthorities());
 		SecurityContext context = SecurityContextHolder.createEmptyContext();

+ 7 - 0
test/src/test/java/org/springframework/security/test/context/showcase/WithMockUserTests.java

@@ -67,6 +67,13 @@ public class WithMockUserTests {
 				.contains("ROLE_ADMIN");
 	}
 
+	@Test
+	@WithMockUser(username = "admin", authorities = { "ADMIN", "USER" })
+	public void getMessageWithMockUserCustomAuthorities() {
+		String message = messageService.getMessage();
+		assertThat(message).contains("admin").contains("ADMIN").contains("USER").doesNotContain("ROLE_");
+	}
+
 	@EnableGlobalMethodSecurity(prePostEnabled = true)
 	@ComponentScan(basePackageClasses = HelloMessageService.class)
 	static class Config {

+ 27 - 0
test/src/test/java/org/springframework/security/test/context/support/WithMockUserSecurityContextFactoryTests.java

@@ -47,6 +47,7 @@ public class WithMockUserSecurityContextFactoryTests {
 		when(withUser.value()).thenReturn("valueUser");
 		when(withUser.password()).thenReturn("password");
 		when(withUser.roles()).thenReturn(new String[] { "USER" });
+		when(withUser.authorities()).thenReturn(new String[] {});
 
 		assertThat(factory.createSecurityContext(withUser).getAuthentication().getName())
 				.isEqualTo(withUser.value());
@@ -58,6 +59,7 @@ public class WithMockUserSecurityContextFactoryTests {
 		when(withUser.username()).thenReturn("customUser");
 		when(withUser.password()).thenReturn("password");
 		when(withUser.roles()).thenReturn(new String[] { "USER" });
+		when(withUser.authorities()).thenReturn(new String[] {});
 
 		assertThat(factory.createSecurityContext(withUser).getAuthentication().getName())
 				.isEqualTo(withUser.username());
@@ -68,6 +70,7 @@ public class WithMockUserSecurityContextFactoryTests {
 		when(withUser.value()).thenReturn("valueUser");
 		when(withUser.password()).thenReturn("password");
 		when(withUser.roles()).thenReturn(new String[] { "USER", "CUSTOM" });
+		when(withUser.authorities()).thenReturn(new String[] {});
 
 		assertThat(
 				factory.createSecurityContext(withUser).getAuthentication()
@@ -75,11 +78,35 @@ public class WithMockUserSecurityContextFactoryTests {
 				"ROLE_USER", "ROLE_CUSTOM");
 	}
 
+	@Test
+	public void authoritiesWorks() {
+		when(withUser.value()).thenReturn("valueUser");
+		when(withUser.password()).thenReturn("password");
+		when(withUser.roles()).thenReturn(new String[] { "USER" });
+		when(withUser.authorities()).thenReturn(new String[] { "USER", "CUSTOM" });
+
+		assertThat(
+				factory.createSecurityContext(withUser).getAuthentication()
+						.getAuthorities()).onProperty("authority").containsOnly(
+				"USER", "CUSTOM");
+	}
+
+	@Test(expected = IllegalStateException.class)
+	public void authoritiesAndRolesInvalid() {
+		when(withUser.value()).thenReturn("valueUser");
+		when(withUser.password()).thenReturn("password");
+		when(withUser.roles()).thenReturn(new String[] { "CUSTOM" });
+		when(withUser.authorities()).thenReturn(new String[] { "USER", "CUSTOM" });
+
+		factory.createSecurityContext(withUser);
+	}
+
 	@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" });
+		when(withUser.authorities()).thenReturn(new String[] {});
 
 		factory.createSecurityContext(withUser);
 	}