Spring Boot CORS配置

时间:2018-08-01 14:02:05

标签: java rest spring-boot cors

我有Spring Boot Rest应用程序。 最近,我已经使用JsonWebToken实现了用户身份验证。

当我使用邮递员进行测试时,一切似乎都可以正常工作, 但是当从Angular Application调用其余部分时,我得到了错误 指的是cors:

  

对预检请求的响应未通过访问控制检查:所请求的资源上不存在“ Access-Control-Allow-Origin”标头。因此,不允许访问来源“ http://localhost:4200”。响应的HTTP状态码为403。

这是我的代码:

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private JwtAuthFilter authFilter;

@Autowired
private JwtAuthenticationProvider authenticationProvider;

@Autowired
private JwtAuthenticationEntryPoint authenticationEntryPoint;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(authenticationProvider);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    //http.csrf().ignoringAntMatchers("/token");
    http.csrf().disable();

    http.cors().and().authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers("/token").permitAll()
            .antMatchers("/rest/**").authenticated()
            .and()
            .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
            .exceptionHandling()
            .authenticationEntryPoint(authenticationEntryPoint);

}


@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS","PUT","DELETE"));
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/rest/**", configuration);
    return source;
}


}

JwtAuthFilter:

@Component
public class JwtAuthFilter implements Filter
{

@Override
public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
{
    HttpServletRequest servletRequest = (HttpServletRequest) request;
    HttpServletResponse response = (HttpServletResponse) servletResponse;

    String authorization = servletRequest.getHeader("Authorization");
    String origin = servletRequest.getHeader("Origin");

    if (authorization != null)
    {
        JwtAuthToken token = new JwtAuthToken(authorization.replaceAll("Bearer ", ""));
        SecurityContextHolder.getContext().setAuthentication(token);
    }

    filterChain.doFilter(servletRequest, response);
}

@Override
public void destroy()
{

}

@Override
public void init(FilterConfig filterConfig) throws ServletException
{

}
}

我的登录Controller映射为“ / token”,所有其他控制器映射为“ / rest / **” 有趣的是,调用“ / token”控制器可以正常工作……它返回令牌和用户详细信息。服务器响应包含:

但是当我调用任何其他控制器...例如“ / rest / task / all”时,我得到了错误,并且没有access-control-allow-credentials和access-control-allow-origin头。

当我更改

source.registerCorsConfiguration("/rest/**", configuration);

到     source.registerCorsConfiguration("/**", configuration);

我收到一个错误,我在access-control-allow-origin标头中有两个值 http://localhost:4200http://localhost:4200

任何人都可以提供:D吗?

1 个答案:

答案 0 :(得分:0)

这是一个古老的问题,我不确定您是否找到答案。我只能提出调试这些问题的方法,因为这些问题通常是非常本地化的。

1.First-仅Java代码不足以调试CORS问题。您需要查看“浏览器网络”选项卡,并查看哪个呼叫失败-OPTIONS呼叫或实际数据呼叫。其次,在浏览器中,需要仔细查看请求和响应标头以查找失败的请求,并特别列出那些。这些下面。

在请求方-Origin

在响应方面-Access-Control-Allow-CredentialsAccess-Control-Allow-HeadersAccess-Control-Allow-MethodsAccess-Control-Allow-Origin

2。

  

当我使用邮递员进行测试时,一切似乎都可以正常工作,但是当   其余的是从Angular Application调用的,我遇到了引用错误   科尔斯:

这是正常现象,因为CORS是浏览器安全功能,并且在任何其他客户端中都可能看不到此问题。 CORS错误并不表示您的API调用未成功,仅表示浏览器抑制了响应并且没有前进。

因此,如果您的API使用者不是网络浏览器,那么您在API方面最可能与CORS无关。其他客户端不会通过包含OPTIONS请求来使其分为两步。

3。配置行-http.cors()将向您的过滤器链添加过滤器-org.springframework.web.filter.CorsFilter,因此请在此处和您的JwtAuthFilter中放置断点,以查看代码流向何处。

4。预期URL的系统行为会有所不同-/token/rest/**,因为令牌URL不安全,而rest / **只允许经过身份验证的用户使用,因此会出现其他过滤器。

Spring Security exclude url patterns in security annotation configurartion

How to disable spring security for particular url

因此,查找CORS问题的理想方法是通过接受有问题的请求并验证响应头-Access-Control-Allow-Origin是否正确填充来调试代码。