Spring Boot CORS 配置不接受授权标头
Posted
技术标签:
【中文标题】Spring Boot CORS 配置不接受授权标头【英文标题】:Spring Boot CORS configuration is not accepting authorization header 【发布时间】:2017-06-21 07:17:54 【问题描述】:Angular2 应用正在向 Spring Boot 发送带有 X-AUTH-TOKEN
标头值的 HTTP GET
请求。每次request.getHeader("X-AUTH-TOKEN")
返回null
。
有趣的是,如果我从 ARC 客户端或任何其他 rest 客户端发送请求,它工作正常。
我还花费了大量时间确保 Angular HTTP GET
请求正在发送 JWT 令牌。
角度代码
getCandidatesByUserId(userId: number): Observable<Candidate[]>
let headers = new Headers( 'X-AUTH-TOKEN': 'let-jwt-test-token-in' );
console.log('Token is '+ headers.get('X-AUTH-TOKEN'));
return this.http.get(this.url+userId+'/candidates',
headers: headers
)
.map((response: Response) => <Candidate[]> response.json())
.do(data => console.log('All: '+ JSON.stringify(data)))
.catch(this.handleError);
JWTFilter
@Override
public void doFilter(ServletRequest request, ServletResponse res, FilterChain filterChain)
throws IOException, ServletException
try
final HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-AUTH-TOKEN, Content-Type, Accept");
response.setHeader("Access-Control-Expose-Headers", "X-AUTH-TOKEN, Content-Type");
HttpServletRequest httpRequest = (HttpServletRequest) request;
Map<String, String> blackListedTokenMap =
(Map<String, String>) ((HttpServletRequest) request)
.getSession()
.getServletContext()
.getAttribute(WebAppListener.TOKEN_BLACK_LIST_MAP);
String authToken = authenticationService.getToken(httpRequest);
if (authToken != null && blackListedTokenMap.containsValue(authToken))
throw new RuntimeException("token invalidated");
UserAuthentication authentication = (UserAuthentication) authenticationService.getAuthentication(httpRequest);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
SecurityContextHolder.getContext().setAuthentication(null);
catch (RuntimeException e)
((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED);
SpringSecurityConfig
@Override
protected void configure(HttpSecurity http) throws Exception
http
.csrf()
.csrfTokenRepository(new HttpSessionCsrfTokenRepository())
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("*/*"));
http
.exceptionHandling()
.and()
.anonymous()
.and()
.servletApi()
.and()
.headers()
.cacheControl();
http
//.addFilterBefore(corsFilter, ChannelProcessingFilter.class)
.authorizeRequests()
.antMatchers("/resources/**").permitAll()// allow for static resources
.antMatchers("/signup").permitAll()
.antMatchers("/forgot").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/reset").permitAll()
.antMatchers("/health").permitAll()
.antMatchers("/hello").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/reset_pw").permitAll()
.anyRequest().authenticated()
.and()
.addFilterAfter(new JJWTFilter(tokenAuthenticationService),
UsernamePasswordAuthenticationFilter.class);
控制台日志
【问题讨论】:
你用的是spring boot吗?我最近有一个类似的问题。一个应用程序在过滤器上使用 Authorization 标头而崩溃。它是空的。确定 @EnableWebMvc 注释搞砸了。 @LucasHolt 是的。我在后端使用SpringBoot
,但在任何地方都没有使用@EnableWebMvc
。
嗨,有这方面的消息吗?我有同样的问题。我可以通过邮递员拨打电话,但不能通过我的 Angular 应用程序拨打电话。
【参考方案1】:
我解决了:
//Define class with this annotation
@Configuration
public class CorsConfig
@Bean
public FilterRegistrationBean corsFilter()
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
// return new CorsFilter(source);
final FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
@Bean
public WebMvcConfigurer mvcConfigurer()
return new WebMvcConfigurerAdapter()
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("GET", "PUT", "POST", "GET", "OPTIONS");
;
你可以定义这个类并在你的启动弹簧类中添加@ComponentScan(basePackageClasses= CorsConfig.class)
或者只是在引导类中使用上述方法。
那么应该可以了。
【讨论】:
以上是关于Spring Boot CORS 配置不接受授权标头的主要内容,如果未能解决你的问题,请参考以下文章
Angular 的 Spring Boot 授权服务器访问 - 不断给出 CORS 错误
Spring Boot Oauth2 授权服务器不接受有效令牌
Keycloak Spring boot 后端和 Angular 前端,CORS 错误
Spring Boot Security 忽略 cors 配置