Spring Security 实现IP白名单机制
Spring Security 实现IP白名单机制本文讨论如何在Spring Security 中实现IP白名单机制。先看看默认实现机制,同时也讨论自定义AuthenticationProvider实现更加灵活的应用。1. 默认实现首先我们看下Java配置。使用hasIpAddress() 定义允许特定ip地址的用户访问特定资源。请看下面使用hasIpAddress()的配置:@Confi...
Spring Security 实现IP白名单机制
本文讨论如何在Spring Security 中实现IP白名单机制。先看看默认实现机制,同时也讨论自定义AuthenticationProvider实现更加灵活的应用。
1. 默认实现
首先我们看下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();
}
// ...
}
上面配置只有"11.11.11.11"地址的用户可以访问“/foos”的资源。使用白名单IP的用户在访问“/foos/”URL之前也不需要登录。如果需要先登录,那么配置表达式如下:
//...
.antMatchers("/foos/**")
.access("isAuthenticated() and hasIpAddress('11.11.11.11')")
//...
1.1. 测试
下面进行简单的测试,确保如预期的工作。首先确保任何用户登录后能访问主页:
@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"));
}
接下来,我们确保即使已认证用户不能访问“/foos”资源,除了白名单IP用户:
@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"));
}
注意,我们不能从本地主机“127.0.0.1”访问“/foos”资源,只有具有“11.11.11.11”的用户才能访问它。
2. 自定义AuthenticationProvider实现
接下来看看如何通过自定义AuthenticationProvider实现更加灵活的限制。
我们已经看到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");
}
//...
}
现在我们在Spring Security配置中使用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地址。因此只有在白名单列表中的用户可以访问系统资源。
这仅仅是个基本实现,但我们可以自定义更强大的AuthenticationProvider。例如,我们可以在注册时存储带有用户详细信息的IP地址,并在验证期间在AuthenticationProvider中对其进行比较。
3. 总结
本文学习了两种方法实现IP白名单机制,尤其是自定义AuthenticationProvider机制功能很强大。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)