当从Angular 16向Java REST API发出请求时,我在头中接收的令牌为null。但是,如果我向Postman提出请求,它会完美地工作。
我有一个Angular的前端和一个Java的后端。Java部分通过Spring Security,OAuth2和JWT进行保护。一旦我在Angular中执行登录并检索令牌,我就试图通过在请求头中发送令牌来获取用户列表。在检查Java时,我总是发现令牌是空的。下面是Angular请求
private urlEndPointUsuarios: string = 'http://localhost:8080/api/usuarios';
constructor(private http: HttpClient, public router: Router,
public authService: AuthService) { }
private agregarAuthorizationHeader() {
let token = this.authService.token;
if (token != null) {
this.httpHeaders = this.httpHeaders.append('Authorization', 'Bearer ' + token);
return this.httpHeaders;
}
return this.httpHeaders;
}
getUsuarios(): Observable<Usuario[]> {
return this.http.get(this.urlEndPointUsuarios, { headers: this.agregarAuthorizationHeader()}).pipe(
map(response => response as Usuario[])
)
}
接下来,接收请求并检查令牌的Java方法如下:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
String token = null;
String username = null;
if (authHeader != null && authHeader.startsWith("Bearer ")) {
token = authHeader.substring(7);
username = jwtService.extractUsername(token);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtService.validateToken(token, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
另一方面,如果我用令牌向Postman发出请求,它会完美地工作。我可以看到我如何在Java中接收令牌,我可以在Postman中查看用户列表。我很感激你的帮助。谢谢
1条答案
按热度按时间nbysray51#
如果你使用的是Angular OAuth2“公共”客户端的库,比如angular-auth-oidc-client,你会遇到更少的问题。它正确处理OAuth2流,进行静默令牌刷新,并自动授权与您配置的主机和路径匹配的请求(并且正确执行:Spring将找到令牌)。
然而,Spring Security团队现在建议只使用“机密”客户端,这意味着您的Angular应用程序应该在运行在服务器上的OAuth2客户端上使用会话cookie进行授权(而不是使用Bearer令牌进行授权以查询OAuth2资源服务器)。
所以有两个选择:
spring-cloud-gateway
可以很容易地与spring-boot-starter-oauth2-client
和TokenRelay=
滤波器一起用于该目的。我写了a tutorial for that。