春季安全性-授权没有oAuth令牌的预发请求

时间:2020-10-16 01:19:50

标签: spring-security oauth cors preflight

我正在尝试在(/ 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("*");
        }
    };
}

2 个答案:

答案 0 :(得分:0)

对于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。希望对您有帮助

答案 1 :(得分:0)

将以下代码段添加到jwkAuthFilter中可以达到目的。

     if (CorsUtils.isPreFlightRequest(request)) {
        response.setStatus(HttpServletResponse.SC_OK);
        return;
    }
相关问题