Spring Boot統合テストのSpring Security
1. 前書き
スタンドアロンの統合環境を必要とせずに統合テストを実行する機能は、ソフトウェアスタックにとって貴重な機能です。 Spring BootとSpring Securityのシームレスな統合により、セキュリティレイヤーと対話するコンポーネントを簡単にテストできます。
このクイックチュートリアルでは、@MockMvcTestと@SpringBootTestを使用してセキュリティ対応の統合テストを実行する方法について説明します。
2. 依存関係
まず、例に必要な依存関係を取り入れましょう。
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.security
spring-security-test
test
spring-boot-starter-web, spring-boot-starter-security,およびspring-boot-starter-test starterは、Spring MVC、Spring Security、およびSpringBootテストユーティリティへのアクセスを提供します。
さらに、使用する@WithMockUserアノテーションにアクセスするために、spring-security-testを取り込みます。
3. Webセキュリティ構成
Webセキュリティ設定は簡単です。 認証されたユーザーのみが/private/に一致するパスにアクセスできます。 /public/に一致するパスは、すべてのユーザーが使用できます。
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth.inMemoryAuthentication()
.passwordEncoder(encoder)
.withUser("spring")
.password(encoder.encode("secret"))
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/private/**")
.authenticated()
.antMatchers("/public/**")
.permitAll()
.and()
.httpBasic();
}
}
4. メソッドのセキュリティ構成
WebSecurityConfigurer,で定義したURLパスベースのセキュリティに加えて、追加の構成ファイルを提供することにより、メソッドベースのセキュリティを構成できます。
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfigurer
extends GlobalMethodSecurityConfiguration {
}
この構成により、SpringSecurityの事前/事後注釈のサポートが有効になります。 追加のサポートが必要な場合は、他の属性も利用できます。 Springメソッドセキュリティの詳細については、article on the topicをご覧ください。
5. @WebMvcTestを使用したコントローラーのテスト
Spring Securityで@WebMvcTestアノテーションアプローチを使用する場合、セキュリティ構成をテストするためにMockMvc is automatically configured with the necessary filter chain が必要です。
MockMvcが構成されているため、追加の構成なしでテストに@WithMockUserを使用できます。
@RunWith(SpringRunner.class)
@WebMvcTest(SecuredController.class)
public class SecuredControllerWebMvcIntegrationTest {
@Autowired
private MockMvc mvc;
// ... other methods
@WithMockUser(value = "spring")
@Test
public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
mvc.perform(get("/private/hello").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
@WebMvcTestを使用すると、コンテキスト全体ではなくWebレイヤーのみをインスタンス化するようにSpringBootに指示されることに注意してください。 このため、controller tests that use @WebMvcTest will run faster than with other approaches。
6. @SpringBootTestを使用したコントローラーのテスト
@SpringBootTestアノテーションを使用してSpring Securityでコントローラーをテストする場合、it’s necessary to explicitly configure the filter chain when setting up MockMvc。
これを行うには、SecurityMockMvcConfigurerが提供する静的なspringSecurityメソッドを使用することをお勧めします。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SecuredControllerSpringBootIntegrationTest {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
}
// ... other methods
@WithMockUser("spring")
@Test
public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
mvc.perform(get("/private/hello").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
7. @SpringBootTestを使用したセキュリティで保護されたメソッドのテスト
@SpringBootTestは、セキュリティで保護されたメソッドをテストするために追加の構成を必要としません。 simply call the methods directly and use @WithMockUser as needed:できます
@RunWith(SpringRunner.class)
@SpringBootTest
public class SecuredMethodSpringBootIntegrationTest {
@Autowired
private SecuredService service;
@Test(expected = AuthenticationCredentialsNotFoundException.class)
public void givenUnauthenticated_whenCallService_thenThrowsException() {
service.sayHelloSecured();
}
@WithMockUser(username="spring")
@Test
public void givenAuthenticated_whenCallServiceWithSecured_thenOk() {
assertThat(service.sayHelloSecured()).isNotBlank();
}
}
8. @SpringBootTestおよびTestRestTemplateを使用したテスト
TestRestTemplateは、セキュリティで保護されたRESTエンドポイントの統合テストを作成するときに便利なオプションです。
simply autowire a template and set credentials before requesting secured endpoints:できます
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SecuredControllerRestTemplateIntegrationTest {
@Autowired
private TestRestTemplate template;
// ... other methods
@Test
public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception {
ResponseEntity result = template.withBasicAuth("spring", "secret")
.getForEntity("/private/hello", String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
}
}
TestRestTemplateは柔軟性があり、多くの便利なセキュリティ関連オプションを提供します。 TestRestTemplateの詳細については、article on the topicを確認してください。
9. 結論
この記事では、セキュリティ対応の統合テストを実行するいくつかの方法を検討しました。
mvccontrollerおよびRESTエンドポイント、およびセキュリティで保護されたメソッドの使用方法を検討しました。
いつものように、ここの例のすべてのソースコードはfound over on GitHubにすることができます。