Procházet zdrojové kódy

Add WithMockJwt Sample tests

Closes gh-318
Josh Cummings před 11 měsíci
rodič
revize
277055548f

+ 77 - 0
servlet/spring-boot/java/oauth2/resource-server/hello-security/src/test/java/example/OAuth2ResourceServerControllerTests.java

@@ -16,12 +16,31 @@
 
 package example;
 
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.junit.jupiter.api.Test;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
 import org.springframework.context.annotation.Import;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+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.SecurityContextImpl;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
+import org.springframework.security.test.context.support.WithSecurityContext;
+import org.springframework.security.test.context.support.WithSecurityContextFactory;
 import org.springframework.test.web.servlet.MockMvc;
 
 import static org.hamcrest.CoreMatchers.is;
@@ -102,4 +121,62 @@ public class OAuth2ResourceServerControllerTests {
 		// @formatter:on
 	}
 
+	@Test
+	@WithMockJwt("classpath:validjwt.json")
+	void indexGreetsAuthenticatedUserWithMockJwt() throws Exception {
+		this.mockMvc.perform(get("/")).andExpect(content().string(is("Hello, ch4mpy!")));
+	}
+
+	@Test
+	@WithMockJwt(value = "classpath:validjwt.json", authorities = "SCOPE_message:read")
+	void messageCanBeReadWithScopeMessageReadAuthorityWithMockJwt() throws Exception {
+		// @formatter:off
+		this.mockMvc.perform(get("/message")).andExpect(content().string(is("secret message")));
+		// @formatter:on
+	}
+
+	@Test
+	@WithMockJwt(value = "classpath:validjwt.json", authorities = "SCOPE_message:read")
+	void messageCanNotBeCreatedWithScopeMessageReadAuthorityWithMockJwt() throws Exception {
+		// @formatter:off
+		this.mockMvc.perform(post("/message")
+				.content("Hello message"))
+				.andExpect(status().isForbidden());
+		// @formatter:on
+	}
+
+	@Retention(RetentionPolicy.RUNTIME)
+	@WithSecurityContext(factory = JwtFactory.class)
+	@interface WithMockJwt {
+
+		String value();
+
+		String[] authorities() default {};
+
+	}
+
+	static class JwtFactory implements WithSecurityContextFactory<WithMockJwt> {
+
+		private final ResourceLoader resourceLoader = new DefaultResourceLoader();
+
+		private final ObjectMapper mapper = new ObjectMapper();
+
+		@Override
+		public SecurityContext createSecurityContext(WithMockJwt annotation) {
+			Resource jwtString = this.resourceLoader.getResource(annotation.value());
+			try (InputStream in = jwtString.getInputStream()) {
+				Map<String, Object> claims = (Map<String, Object>) this.mapper.readValue(in, Map.class);
+				Jwt jwt = Jwt.withTokenValue("token").header("alg", "none").claims((c) -> c.putAll(claims)).build();
+				Collection<GrantedAuthority> authorities = Stream.of(annotation.authorities())
+					.map(SimpleGrantedAuthority::new)
+					.collect(Collectors.toList());
+				return new SecurityContextImpl(new JwtAuthenticationToken(jwt, authorities));
+			}
+			catch (Exception ex) {
+				throw new RuntimeException(ex);
+			}
+		}
+
+	}
+
 }

+ 1 - 0
servlet/spring-boot/java/oauth2/resource-server/hello-security/src/test/resources/validjwt.json

@@ -0,0 +1 @@
+{ "sub" : "ch4mpy" }