我找到了解决方案。我不确定这是不是最好的方法,但它可以工作。这就是解决方案。
首先,我们可以定义一个实现 AccessDecisionManager 的类:
@Service
public class ResourceAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
throws
AccessDeniedException, InsufficientAuthenticationException {
//...
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
String ip = request.getRemoteHost();
Object principal = authentication.getPrincipal();
User user;
if (principal instanceof User){
user=(User)principal;
if (!ip.equals(user.getIpConfig())){
throw new AccessDeniedException("wrong ip");
}
}
//...
}
//...
}
当然,您必须将 ip 配置存储在 User 类中。
然后,我们定义一个类 extends AbstractSecurityInterceptor implements Filter:
@Service
public class ResourceFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
//...
@Autowired
public void setMyAccessDecisionManager(ResourceAccessDecisionManager resourceAccessDecisionManager) {
super.setAccessDecisionManager(resourceAccessDecisionManager);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain);
invoke(fi);
}
private void invoke(FilterInvocation fi) throws IOException, ServletException {
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
//...
}
并将过滤器添加到安全配置类中:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final ResourceService resourceService;
private final UserService userService;
private final HttpServletRequest request;
private final ResourceFilterSecurityInterceptor resourceFilterSecurityInterceptor;
private final EnvironmentConfig environmentConfig;
@Autowired
public SecurityConfiguration(ResourceService resourceService, UserService userService,
HttpServletRequest request,
ResourceFilterSecurityInterceptor resourceFilterSecurityInterceptor,
EnvironmentConfig environmentConfig) {
this.resourceService = resourceService;
this.userService = userService;
this.request = request;
this.resourceFilterSecurityInterceptor = resourceFilterSecurityInterceptor;
this.environmentConfig = environmentConfig;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic().and()
.authorizeRequests()
.antMatchers("/order/**").authenticated()
.anyRequest().authenticated()
.and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
;
http.addFilterBefore(resourceFilterSecurityInterceptor,FilterSecurityInterceptor.class);
// @formatter:on
}
//...
}
现在它可以工作了,但欢迎提出任何改进解决方案的建议。