问题描述
我正在尝试在(/ secure / **)中授权所有预检请求,而没有授权标头(在我的情况下为oauth令牌)。 JwkFilter用于验证授权标头中传递的oauth令牌。任何建议,我在这里哪里出错了。
@Override
protected void configure(HttpSecurity http) throws Exception {
JwtAuthFilter jwtAuthTokenFilter = new JwtAuthFilter(oauthConfig);
jwtAuthTokenFilter.setAuthenticationManager(getAuthManager());
http.cors().and().authorizeRequests().antMatchers(HttpMethod.OPTIONS,"/secure/**")
.permitAll();
http.requiresChannel().anyRequest().requiresSecure().and()
.addFilterBefore(requireProtocolFilter,ChannelProcessingFilter.class).sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().anonymous().disable().csrf().disable()
.antMatcher("/**").authorizeRequests().anyRequest().permitAll().and()
.antMatcher(/secure/**")
.addFilterBefore(jwtAuthTokenFilter,BasicAuthenticationFilter.class).exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint()).and().authorizeRequests().anyRequest()
.authenticated();
}
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("*");
}
};
}
解决方法
对于spring来说,对于CORS的预检请求,它们将在您的jwtAuthTokenFilter(在BasicAuthenticationFilter过滤器之前注册)之前执行->正确
在此处指定了订单(in spring code):
FilterComparator() {
Step order = new Step(INITIAL_ORDER,ORDER_STEP);
...
put(CorsFilter.class,order.next());
...
put(BasicAuthenticationFilter.class,order.next());
...
}
在CORS中,对于复杂的请求(例如在您的情况下使用自定义标头Authorization标头),浏览器将在发送实际请求之前先发送预检请求,以了解服务器是否允许客户端访问其资源。
CORSFilter将像这样(in spring code)执行:
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain filterChain) throws ServletException,IOException {
CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
boolean isValid = this.processor.processRequest(corsConfiguration,request,response);
if (!isValid || CorsUtils.isPreFlightRequest(request)) {
return;
}
filterChain.doFilter(request,response);
}
}
他们将检查是否每个预检请求(扩展一次PerPerRequestFilter)都到达服务器,processRequest有效还是终止链的预检请求。 这是检查预检请求(in spring code)的默认处理器:
public class DefaultCorsProcessor implements CorsProcessor {
@Override
public boolean processRequest(@Nullable CorsConfiguration config,HttpServletRequest request,HttpServletResponse response) throws IOException {
...
boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
if (config == null) {
if (preFlightRequest) {
rejectRequest(new ServletServerHttpResponse(response));
return false;
}
else {
return true;
}
}
return handleInternal(new ServletServerHttpRequest(request),new ServletServerHttpResponse(response),config,preFlightRequest);
}
就您而言,我认为您缺少用于启用CORS的配置。 因此服务器拒绝客户端请求(通过发送HttpStatus.FORBIDDEN代码),以便浏览器不向服务器发送实际请求。 而且您的JwtAuthTokenFilter没有执行的机会。
您可以参考this post来配置cors。希望对您有帮助
,将以下代码段添加到jwkAuthFilter中可以达到目的。
if (CorsUtils.isPreFlightRequest(request)) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}