我想通过基本身份验证保护一个端点,并仅允许来自特定 IP 地址的请求。过滤基本身份验证:
SecurityFilterChain basicAuthSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/test").authenticated()
.anyRequest().permitAll()
)
.csrf().disable()
.httpBasic();
return http.build();
}
IP 地址过滤器:
SecurityFilterChain ipSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/test").access(hasIpAddress("127.0.0.1"))
.anyRequest().permitAll()
)
.csrf().disable();
return http.build();
}
private AuthorizationManager<RequestAuthorizationContext> hasIpAddress(String ipAddress) {
IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(ipAddress);
return (authentication, context) -> {
HttpServletRequest request = context.getRequest();
return new AuthorizationDecision(ipAddressMatcher.matches(request));
};
}
问题在于如何将这些解决方案结合起来。对于较旧的 Spring,我可以使用
.access("isAuthenticated() and hasIpAddress('127.0.0.1')")
但现在这个方法只接受 AuthorizationManager 而不是 String。
您可以创建一个辅助方法来创建与特定 IP 匹配的
AuthorizationManager
:
private AuthorizationManager<RequestAuthorizationContext> hasIpAddress(String ipAddress) {
IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(ipAddress);
return (authentication, context) -> {
HttpServletRequest request = context.getRequest();
return new AuthorizationDecision(ipAddressMatcher.matches(request));
};
}
与这些静态导入一起:
import static org.springframework.security.authorization.AuthenticatedAuthorizationManager.authenticated;
import static org.springframework.security.authorization.AuthorizationManagers.allOf;
然后您可以将代码完善为:
http.authorizeHttpRequests()
.requestMatchers("/test").access(allOf(authenticated(), hasIpAddress("127.0.0.1")))
.anyRequest().permitAll();