Spring Security - 白名单IP范围

时间:2017-02-10 17:05:42

标签: java security spring-mvc spring-boot spring-security

我查看过的很多资源和stackoverflow问题都提供了使用.xml文件的答案:

我想知道的是,如果可以在不使用XML配置的情况下使用Spring Security将IP地址范围列入白名单?

以下是我控制器中的一个简单方法:

@RequestMapping(value = "/makeit", method = RequestMethod.GET)
@ResponseBody
//@PreAuthorize("hasIpAddress('192.168.0.0/16')")
public String requestData() {

    return "youve made it";
}

我为安全配置创建了一个单独的类,但它没有太多,我只是为EnableGlobalMethodSecurity注释创建了它 - 这样我就可以使用@PreAuthorize注释(来自在这里回答:@PreAuthorize annotation not working spring security)。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http
            .authorizeRequests()
                .anyRequest().access("hasIpAddress('0.0.0.0/0')");

        /*http
            .authorizeRequests()
                .anyRequest().hasIpAddress("0.0.0.0/0");*/

        /*http
            .authorizeRequests()
                .antMatchers("/**").hasIpAddress("0.0.0.0/0");*/

        /*http
            .authorizeRequests()
                .antMatchers("/**").access("hasIpAddress('0.0.0.0/0')");*/

        /*http
            .authorizeRequests()
                .anyRequest().access("hasIpAddress('0.0.0.0/0')");*/

    }
}

然而,当我尝试时,它回复了(通过POSTMAN):

{
  "timestamp": 1486743507520,
  "status": 401,
  "error": "Unauthorized",
  "message": "Full authentication is required to access this resource",
  "path": "/makeit"
}

其他事实:

我的IP地址在此范围内。我正在使用Spring版本1.3.1(我相信Spring Security是4.0.3)。

2 个答案:

答案 0 :(得分:3)

如果有人需要,我会用 AuthenticationProvider 发布解决方案。如果你有大量的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。

答案 1 :(得分:2)

所以在@Dur的帮助下,我们能够解决问题。问题不在于Spring Boot(上面一切正常)但问题是当用户本地访问Spring App(localhost:8080)时,localhost使用IPv6地址,上面的代码允许访问IPv4地址。

您需要通过将IPv4地址更改为IPv6(或Tomcat默认设置)来更改SpringSecurityConfig文件,或者您可以更改访问应用程序的方式(转到127.0.0.1:8080)。

注意 - 这仅适用于本地测试。您需要测试并获取将访问您的应用的用户/服务的IP地址。

简而言之,您可以在没有AuthenticationManagerBuilder的情况下使用上述代码将IP范围列入白名单。