1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Controllerのテスト時にMockMvcでアクセス元IPアドレスをモックする

Posted at

結論

RequestPostProcessorを実装してテスト実行時にremoteAddrを上書きすれば良い。

環境

  • kotlin 1.9.22
  • spring-boot 3.2.1
  • spring-security 6.2.1

SpringSecurityの設定は以下だとします。

SecurityConfig
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
    http.authorizeHttpRequests { authorizationManagerRequestMatcherRegistry ->
        authorizationManagerRequestMatcherRegistry
            // /dummyへのアクセスは特定のIP(仮にxxx.xxx.xxx.xxxとする)の場合だけ許可する
            .requestMatchers("/dummy")
            .access(WebExpressionAuthorizationManager("hasIpAddress('xxx.xxx.xxx.xxx')"))
            // その他のURLは全て許可する
            .anyRequest().permitAll()
    return http.build()
}

※Controllerのコードは今回重要でないので割愛します。

テストコード

まずIP制限を考慮せずにUnitTestをMockMvcで以下の様に実装します。

HogeControllerTest
@Test
fun test_ip_restrictions() {
    mockMvc
        .get("/dummy")
        .andExpect {
            status { isOk() }
        }
}

上記のテストを実行するとIP制限されているためHTTPステータスが403となりテストが失敗します。IP制限を通過させるためにはアクセス元IPをモックする必要があります。

アクセス元IPをモックするには以下のRequestPostProcessorを実装してrequestをモックする必要がありました。

RequestPostProcessor
package org.springframework.test.web.servlet.request;

import org.springframework.mock.web.MockHttpServletRequest;

@FunctionalInterface
public interface RequestPostProcessor {
    MockHttpServletRequest postProcessRequest(MockHttpServletRequest request);
}

今回はRequestUtilsというテスト用のユーティリティーobjectを作成してIPアドレスをモック出来るようにしました。

object RequestUtils {
    fun remoteAddr(remoteAddr: String): RequestPostProcessor = RequestPostProcessor { request ->
        request.remoteAddr = remoteAddr
        request
    }
}

先ほどのテストケースを以下の様に修正します。

HogeControllerTest
@Test
fun test_ip_restrictions() {
    mockMvc
        .get("/dummy") {
             // 許可されているIPアドレスを指定する
            with(remoteAddr("xxx.xxx.xxx.xxx"))
        }
        .andExpect {
            status { isOk() }
        }
}

こうする事でテスト時にIP制限されたURLへのテストを通過させることができます。

許可されているIPアドレス以外からは403エラーとなるテストも書くと良いです。

HogeControllerTest
@Test
fun test_ip_restrictions_forbidden() {
    mockMvc
        .get("/dummy") {
             // 許可されていないIPアドレスを指定する
            with(remoteAddr("yyy.yyy.yyy.yyy"))
        }
        .andExpect {
            // 403 error
            status { isForbidden() }
        }
}

以上です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?