oauth2.0 从Angular 16到Rest API的令牌请求问题

ax6ht2ek  于 12个月前  发布在  Angular
关注(0)|答案(1)|浏览(131)

当从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中查看用户列表。我很感激你的帮助。谢谢

nbysray5

nbysray51#

如果你使用的是Angular OAuth2“公共”客户端的库,比如angular-auth-oidc-client,你会遇到更少的问题。它正确处理OAuth2流,进行静默令牌刷新,并自动授权与您配置的主机和路径匹配的请求(并且正确执行:Spring将找到令牌)。
然而,Spring Security团队现在建议只使用“机密”客户端,这意味着您的Angular应用程序应该在运行在服务器上的OAuth2客户端上使用会话cookie进行授权(而不是使用Bearer令牌进行授权以查询OAuth2资源服务器)。
所以有两个选择:

  • 将后端conf从OAuth2资源服务器更改为带有登录的OAuth2客户端(或者将其转换为根本不是OAuth2的内容:如果您不使用SSO,那么表单登录可能是一个可以考虑选项)
  • 在Angular和配置为OAuth2客户端的资源服务器之间引入Backend For Frontend(BFF),并将会话授权桥接到Bearer token 1。spring-cloud-gateway可以很容易地与spring-boot-starter-oauth2-clientTokenRelay=滤波器一起用于该目的。我写了a tutorial for that

相关问题