CORS:响应中缺少授权标头(jQuery / Spring)
Posted
技术标签:
【中文标题】CORS:响应中缺少授权标头(jQuery / Spring)【英文标题】:CORS: Missing Authorization Header in Response (jQuery / Spring) 【发布时间】:2018-12-31 01:25:43 【问题描述】:我有一个在 localhost:8080 上运行的 Spring-Boot Web-Server 和一个在 localhost:80 上带有一些“静态”html/js 的 Apache HTTP-Server。我用 JWT-Authorization 实现了一个 RESTful-API。
如果我确实在与 REST-API 相同的服务器上提供静态 html/js,当我请求 /login-Endpoint 时,我成功地将 JWT-Token 检索为“Authorization”-Header。
但是当我做同样的事情时,在我的 Apache 服务器上提供静态源时,Authorization-Header 丢失了。我的 javascript:
$.ajax(
type: "POST",
url: "http://localhost:8080/login",
data: JSON.stringify(data),
contentType: "application/json",
dataType: "json",
success: function (data)
alert(data);
,
failure: function (errMsg)
alert(errMsg);
,
complete: function (resp)
console.log(resp.getAllResponseHeaders());
console.log(resp.getResponseHeader("authorization"));
);
console.log(resp.getAllResponseHeaders()):
pragma: no-cache cache-control: no-cache, no-store, max-age=0, must-revalidate expires: 0
console.log(resp.getResponseHeader("authorization")):
null
我已经做了很多研究,我认为原因是 CORS 配置错误。
我的 WebSecurity-Class 看起来像这样 - 尽可能多地允许(出于测试目的):
@EnableWebSecurity public class WebSecurity extends WebSecurityConfigurerAdapter
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL).permitAll().anyRequest().authenticated().and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
@Bean
public CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
还有什么建议吗?
(我调试了我的 Java-Code 并且 JWT-Token 成功添加到响应中 - 但我的 js 没有收到它..)
【问题讨论】:
通常 JWTAuthorizationFilter 与授权标头一起使用。过滤器验证标头授权中的 jwt。请查看以下链接以了解更多关于 JWTAuthorizationFilter auth0.com/blog/implementing-jwt-authentication-on-spring-boot 您应该在 AJAX 请求中传递 Authorization 标头以获得成功的结果或从 CORS 中删除过滤器 @VinuBibin :这正是我用于构建 Spring-setup 的资源。正如我所提到的 - 如果 html/js 源在同一台服务器上提供,那么一切正常。但是,如果 html/js-sources 在不同的服务器 (CORS) 上提供,则缺少授权标头.. 您能否在您的问题中添加带有标头的请求和响应的痕迹?同时在浏览器中显示错误消息(使用浏览器的开发工具)。 【参考方案1】:您的 CORS 配置对我来说似乎不正确。
您可以在 Spring 中配置多个级别的 CORS
全局 CORS 配置
为整个应用启用 CORS 非常简单:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**");
如果你使用的是 Spring Boot,建议只声明一个 WebMvcConfigurer bean
@Configuration
public class MyConfiguration
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**");
;
方法级别
@RestController
@RequestMapping("/account")
public class AccountController
@CrossOrigin
@GetMapping("/id")
public Account retrieve(@PathVariable Long id)
// ...
@DeleteMapping("/id")
public void remove(@PathVariable Long id)
// ...
班级等级
@CrossOrigin
@RestController
@RequestMapping("/account")
public class AccountController
@GetMapping("/id")
public Account retrieve(@PathVariable Long id)
// ...
@DeleteMapping("/id")
public void remove(@PathVariable Long id)
// ...
更多详情here
编辑 1
如果你使用的是 Spring Security,你可以这样配置
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http
// by default uses a Bean by the name of corsConfigurationSource
.cors().and()
...
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
更多详情here
【讨论】:
没有这样的全局 CORS 配置。您的 global 配置仅适用于 Spring MVC 调度程序 servlet。它比 OP 问题中的 Spring Security 配置更本地化,它适用于所有 URL,除非您明确忽略某些 URL。 是的,我错过了安全部分。谢谢你的收获。我已经更新了我的答案。以上是关于CORS:响应中缺少授权标头(jQuery / Spring)的主要内容,如果未能解决你的问题,请参考以下文章
django-cors-headers 和 nginx 配置:预检响应缺少 CORS 标头
当提供商因缺少授权标头而拒绝飞行前请求时,让客户端 CORS 工作
*** API 响应中缺少 CORS 标头“Access-Control-Allow-Origin”[重复]