Spring Security - ホワイトリストのIP範囲

1.概要

このチュートリアルでは、Spring SecurityでIP範囲をホワイトリストに登録する方法について説明します。

JavaとXMLの両方の設定を見ていきます。カスタムの AuthenticationProvider を使用してIP範囲をホワイトリストに登録する方法についても説明します。

2. Javaの設定

まず、Javaの設定を調べてみましょう。

  • 特定のIPアドレスを持つユーザーだけが特定のリソースにアクセスできるように hasIpAddress() を使用できます。

これは hasIpAddress() を使った簡単なセキュリティ設定です:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/login").permitAll()
          .antMatchers("/foos/** ** ").hasIpAddress("11.11.11.11")
          .anyRequest().authenticated()
          .and()
          .formLogin().permitAll()
          .and()
          .csrf().disable();
    }

   //...

}

この構成では、IPアドレス「11.11.11.11」を持つユーザーのみが「/foos」リソースにアクセスできます。ホワイトリストに登録されたIPを持つユーザーは、「/foos/」というURLにアクセスする前にログインする必要もありません。

「11.11.11.11」IPを持つユーザーが最初にログインするようにしたい場合は、次の形式の式でこのメソッドを使用できます。

----//...
.antMatchers("/foos/** ** ")
.access("isAuthenticated() and hasIpAddress('11.11.11.11')")//...
----

3. XMLの設定

次に、XML設定を使用してIP範囲をホワイトリストに登録する方法を見てみましょう。

ここでも hasIpAddress() を使用します。

<security:http>
    <security:form-login/>
    <security:intercept-url pattern="/login" access="permitAll()"/>
    <security:intercept-url pattern="/foos/** ** " access="hasIpAddress('11.11.11.11')"/>
    <security:intercept-url pattern="/** ** " access="isAuthenticated()"/>
</security:http>
//...

4.ライブテスト

これで、すべてが正しく機能していることを確認するための簡単なライブテストです。

まず、ログイン後はどのユーザーもホームページにアクセスできるようにします。

@Test
public void givenUser__whenGetHomePage__thenOK() {
    Response response = RestAssured.given().auth().form("john", "123")
      .get("http://localhost:8082/");

    assertEquals(200, response.getStatusCode());
    assertTrue(response.asString().contains("Welcome"));
}

次に、認証されたユーザーでも、IPがホワイトリストに登録されていない限り、 "/foos"リソースにアクセスできないようにします。

@Test
public void givenUserWithWrongIP__whenGetFooById__thenForbidden() {
    Response response = RestAssured.given().auth().form("john", "123")
      .get("http://localhost:8082/foos/1");

    assertEquals(403, response.getStatusCode());
    assertTrue(response.asString().contains("Forbidden"));
}

“ 11.11.11.11”を持つユーザーだけがアクセスできるので、ローカルホスト“ 127.0.0.1”から“/foos”リソースにアクセスすることはできません。

5.カスタム AuthenticationProvider を使用したホワイトリスト登録

最後に、カスタムの AuthenticationProvider ** を作成してIP範囲をホワイトリストに登録する方法を説明します。

IP範囲をホワイトリストに登録するために hasIpAddress() を使用する方法、およびそれを他の表現と組み合わせる方法を説明しました。しかし時々、私たちはもっとカスタマイズが必要です。

次の例では、複数のIPアドレスがホワイトリストに登録されており、それらのIPアドレスのユーザーだけがシステムにログインできます。

@Component
public class CustomIpAuthenticationProvider implements AuthenticationProvider {

   Set<String> whitelist = new HashSet<String>();

    public CustomIpAuthenticationProvider() {
        whitelist.add("11.11.11.11");
        whitelist.add("12.12.12.12");
    }

    @Override
    public Authentication authenticate(Authentication auth) throws AuthenticationException {
        WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails();
        String userIp = details.getRemoteAddress();
        if(! whitelist.contains(userIp)){
            throw new BadCredentialsException("Invalid IP Address");
        }
       //...
}

それでは、セキュリティ設定で CustomIpAuthenticationProvider を使用します。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomIpAuthenticationProvider authenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.authenticationProvider(authenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/login").permitAll()
          .anyRequest().authenticated()
          .and().formLogin().permitAll()
          .and().csrf().disable();
    }

}

ここでは、 WebAuthenticationDetailsのgetRemoteAddress() メソッドを使用してユーザーのIPアドレスを取得しました。

その結果、ホワイトリストに登録されたIPを持つユーザーだけが私たちのシステムにアクセスすることができます。

これは基本的な実装ですが、ユーザーのIPアドレスを使用しながら、 AuthenticationProvider をカスタマイズできます。たとえば、サインアップ時にIPアドレスをユーザーの詳細と共に格納し、認証中に AuthenticationProvider. で比較することができます。

6.まとめ

JavaとXMLの設定を使用して、Spring SecurityのIP範囲をホワイトリストに登録する方法を学びました。また、カスタムの AuthenticationProvider を作成してIP範囲をホワイトリストに登録する方法も学びました。

完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-security-mvc-boot[over on GitHub]にあります。

前の投稿:GSONを使用してJSONからKotlinデータクラスを変換する
次の投稿:JavaのPlayフレームワークを使ったREST API