【发布时间】:2020-05-07 05:07:13
【问题描述】:
当我向使用 Spring Boot 设计的后端控制器发送请求时,我收到一个空授权标头。但是当我使用 Postman 发送相同的请求时,会命中正确的 API,并且会从后端正确获取数据。
在 Spring Boot 方面,这是 JwtSecurityConfiguration.java 的代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "**/**").permitAll()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(entryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();
}
我在JwtAuthenticationToken.java 中收到null 授权标头:
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer ")) {
System.err.println("Header: " + header);
LOGGER.error("JWT Token is either missing from HTTP header or has been provided in an incorrect format!");
throw new AuthenticationCredentialsNotFoundException(
"JWT Token is either missing from HTTP header or has been provided in an incorrect format!");
}
String authenticationToken = header.substring(7);
JwtAuthenticationToken jwtAuthenticationToken = new JwtAuthenticationToken(authenticationToken);
LOGGER.error("JWT Token has been received successfully. Authentication is in progress...");
return getAuthenticationManager().authenticate(jwtAuthenticationToken);
}
在等式的 Angular 方面,我使用 HTTP 拦截器将 JWT 令牌添加到发送的每个请求中。这是我的HttpInterceptorAuth.service.ts 的样子:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let jwtAuthHeader = this._authSvc.getAuthorizedToken();
let jwtAuthUsername = this._authSvc.getLoggedInUsername();
if (jwtAuthHeader && jwtAuthUsername) {
request = request.clone({
setHeaders: {
Authorization: jwtAuthHeader
}
});
}
console.log(request);
return next.handle(request);
}
由于我正在记录 HTTP 拦截器发送的请求,因此在 Chrome 控制台中是这样的:
在 Chrome 开发工具的网络选项卡上,这是 Chrome 发送的请求:
请注意OPTIONS 请求失败并显示401 Unauthorized。
这可能是因为在后端,当 HTTP 拦截器使用授权标头中的 JWT 令牌更新请求时,我收到了一个空的授权标头。
我不知道为什么实际发送的请求与 HTTP 拦截器更新的请求不同。我该如何解决这个问题?
【问题讨论】:
-
浏览器不会将授权添加到预检 OPTIONS 请求。 Spring Security 内置了 CORS 处理,您只需要启用它即可;参见例如baeldung.com/spring-security-cors-preflight
-
似乎是后端问题,您的角度代码看起来不错。
-
好的。这是我第一次使用 JWT。问题是我需要从角度访问 Spring Boot 中的控制器 API,这需要 JWT 令牌才能访问 Spring Boot 控制器 API。我需要在 Authorization 标头中发送该 JWT 令牌。由于存在授权标头,因此浏览器会发送预检请求检查。那么,我该如何避免预检请求检查呢?
-
你没有避免它,你正确地处理它。见developer.mozilla.org/en-US/docs/Web/HTTP/CORS。
-
您对如何修改我的后端代码以便我可以正确处理预检请求有任何指示吗?我不知道是否需要从后端显式处理预检请求。
标签: angular spring-boot spring-security cors jwt