CORS 错误和带有 JWT 令牌的 403 响应
Posted
技术标签:
【中文标题】CORS 错误和带有 JWT 令牌的 403 响应【英文标题】:CORS error and 403 response with JWT token 【发布时间】:2018-09-24 16:51:13 【问题描述】:我正在尝试通过 JWT 令牌保护我的 Web 应用程序,但是当我尝试从我的 Angular 应用程序 (localhost:4200) 向我的 Spring Boot 应用程序 (localhost:8080) 发出请求时,我收到以下错误:
仅从消息中我可以看出这是一个CORS
问题,问题是我已经在后端启用了来自不同来源的请求,这里是它的代码:
更新:我已将 OPTIONS 添加到 allowedMethods()
,但错误仍然相同。
@Configuration
public class AppConfiguration
@Autowired
private Environment env;
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD","OPTIONS")
.allowedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
.exposedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
.maxAge(3600);
;
这也是我的 Angular 应用程序的代码:
baseUrl = 'http://localhost:8080/api/';
constructor(private http: Http)
private postaviHeadere() : RequestOptions
let headers = new Headers();
console.log("***************** Set Headers *****************");
console.log('Getting token from local storage:');
console.log(localStorage.getItem('jwt_token'))
console.log("***********************************************");
headers.append('JWT_TOKEN', localStorage.getItem('JWT_TOKEN'));
let options = new RequestOptions(headers : headers);
console.log(options);
return options;
getUserByToken(): any
return this.http.get(this.baseUrl + 'user/secured', this.postaviHeadere())
【问题讨论】:
您还应该添加OPTION
。应该像.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTION")
执行选项请求时会收到 403。您能否显示该请求的响应标头/正文(如果有)。选项是否在网络服务器级别启用?
CORS issue - No 'Access-Control-Allow-Origin' header is present on the requested resource的可能重复
【参考方案1】:
创建一个java类“CorsFilterConfig”:
@Component
public class CorsFilterConfig extends OncePerRequestFilter
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(request.getMethod()))
response.setStatus(HttpServletResponse.SC_OK);
else
filterChain.doFilter(request, response);
然后将其调用到您的 WebSecurityConfig :
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
httpSecurity
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
// Un-secure H2 Database
.antMatchers("/h2-console/**/**").permitAll()
//whitelist swagger configuration
.antMatchers(
"/swagger-resources/**",
"/api/swagger-resources/**",
"/api/**",
"/null/**",
"/v2/api-docs/**",
"/webjars/springfox-swagger-ui/**",
"/"
).permitAll()
.anyRequest().authenticated();
httpSecurity.cors();
// Custom JWT based security filter
JwtAuthorizationTokenFilter authenticationTokenFilter =
new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil, tokenHeader);
httpSecurity.addFilterBefore(new CorsFilterConfig(), ChannelProcessingFilter.class);
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
【讨论】:
【参考方案2】:您也必须允许 OPTIONS
方法:
@Configuration
public class AppConfiguration
@Autowired
private Environment env;
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")
.allowedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
.exposedHeaders("Content-Type", "Date", "Total-Count", "loginInfo")
.maxAge(3600);
;
【讨论】:
感谢您的快速回复。可悲的是,这并没有解决我的问题。错误保持不变。 OPTIONS 响应现在是否返回 CORS 标头?由于您似乎也获得了 403 状态,因此安全配置可能存在其他问题。你能提供更多关于 Spring Security 的配置吗?【参考方案3】:我已通过将 jwt_token 添加到配置中来解决此问题:
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD","OPTIONS")
.allowedHeaders("Content-Type", "Date", "Total-Count", "loginInfo","jwt_token")
.exposedHeaders("Content-Type", "Date", "Total-Count", "loginInfo", "jwt_token")
.maxAge(3600);
;
感谢大家的帮助!
【讨论】:
以上是关于CORS 错误和带有 JWT 令牌的 403 响应的主要内容,如果未能解决你的问题,请参考以下文章
AWS 无服务器自定义 jwt 授权方 lambda 设置 cors 响应
如何在授权标头中将带有 fetch 和 cors 的 JWT 令牌发送到 Express 服务器?
Spring security Access-Control-Allow-Origin: * (CORS) issue on invalid JWT token
使用spring security的auth api调用的cors错误