1. 概要

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

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

2. Java構成

まず、Java構成について見ていきましょう。

hasIpAddress()を使用して、特定のIPアドレスを持つユーザーのみが特定のリソースにアクセスできるようにすることができます

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範囲をホワイトリストに登録する方法を説明します。

hasIpAddress()を使用してIP範囲をホワイトリストに登録する方法と、それを他の式と混合する方法を見てきました。 ただし、さらにカスタマイズが必要な場合もあります

次の例では、複数の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構成を使用して、SpringSecurityでIP範囲をホワイトリストに登録する方法を学びました。 また、カスタム AuthenticationProvider を作成して、IP範囲をホワイトリストに登録する方法も学びました。

完全なソースコードは、GitHubにあります。