我遇到了完全相同的问题。经过一番研究,我发现问题是由 Spring Boot 2 引起的,而不是由 Spring Security 配置引起的。根据Spring Boot 2.0 migration guide:
为 ASYNC、ERROR 和 REQUEST 调度程序类型配置了 Spring Security 和 Spring Session 过滤器。
以及 Spring Boot 的 SecurityFilterAutoConfiguration 源代码:
@Bean
@ConditionalOnBean(name = DEFAULT_FILTER_NAME)
public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(
SecurityProperties securityProperties) {
DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
DEFAULT_FILTER_NAME);
registration.setOrder(securityProperties.getFilter().getOrder());
registration.setDispatcherTypes(getDispatcherTypes(securityProperties));
return registration;
}
private EnumSet<DispatcherType> getDispatcherTypes(
SecurityProperties securityProperties) {
if (securityProperties.getFilter().getDispatcherTypes() == null) {
return null;
}
return securityProperties.getFilter().getDispatcherTypes().stream()
.map((type) -> DispatcherType.valueOf(type.name())).collect(Collectors
.collectingAndThen(Collectors.toSet(), EnumSet::copyOf));
}
securityProperties.getFilter().getDispatcherTypes() 的默认值在 SecurityProperties 中定义为:
private Set<DispatcherType> dispatcherTypes = new HashSet<>(
Arrays.asList(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST));
因此,默认情况下,Spring Boot 配置 Spring Security,使其过滤器不会应用于 FORWARD 请求(但仅适用于 ASYNC、ERROR 和 REQUEST),因此在将请求转发到时不会应用安全过滤器来验证请求/oauth/token.
解决方案很简单。您可以将以下行添加到您的 application.properties,以便将默认过滤器应用于所有转发的请求
spring.security.filter.dispatcher-types=async,error,request,forward
或使用路径匹配器和 dispatcherType=FORWARD 创建您自己的自定义过滤器链,以仅过滤转发到 /oauth/token 的请求。