Angular - 在 API 调用的 header 请求中未发送不记名令牌

Angular - Bearer token not sent in request header on API calls

由于结果比预期的要长,这里有一个 tl;dr:

我的 Angular 应用程序没有将从 Azure AD 接收的不记名令牌发送到 API,因此 API returns 没有发送 401 响应。 该设置基于 blog post 对如何实施的解释。 博客 post 中提到的示例应用程序适用于我的 Azure AD 设置,并在 API 调用中正确提供令牌。

长版:

我正在开发一个相对简单的基于 Angular 的 front-end,带有 Spring 启动 back-end。 Front-end 和 back-end 通过 REST API 进行通信。该应用程序部署在 Azure Spring 云上。 对于用户身份验证,应用程序请求并从 Azure AD 接收持有者令牌。然后它应该将此令牌与每个 REST 请求一起传输到 API.

我按照此 blog post 进行了必要的更改。 Azure AD 确实提供了有效的 JWT 令牌。

我的问题是,令牌未传递到 REST 调用中的 back-end,因此身份验证失败并返回 401 状态。

下面是我在front-end这边做的相关配置(根据链接的博客post中的描述):

app.module.ts

    @NgModule({
      imports: [
        ...
        HttpClientModule,
        OAuthModule.forRoot({
          resourceServer: {
            allowedUrls: ['http://localhost:8020/api', 'http://localhost:4200/api'], //environment.allowedUrls,
            sendAccessToken: true
          }
        })
    ...
      ],
      declarations: [AppComponent],
      providers: [{ provide: APP_BASE_HREF, useValue: environment.baseHref }],
      bootstrap: [AppComponent]
    })

auth.config.ts

    import { AuthConfig } from 'angular-oauth2-oidc';
    import {environment} from "../environments/environment";
    
    export const authConfig: AuthConfig = {
      issuer: 'https://login.microsoftonline.com/*****************61ea/v2.0',
      redirectUri: window.location.origin + environment.redirectURIPath,
      clientId: '*****************cf76',
      responseType: 'code',
      strictDiscoveryDocumentValidation: false,
      scope: 'openid api://*****************cf76/Rest.Api',
    }

客户和租户 ID“模糊”了。但他们是正确的。 Screenshot of the app overview on Azure (Tenant and Client ID)

app.component.ts

    export class AppComponent {

      constructor(private oauthService: OAuthService, private apiService: ApiService, private adapterService: AdapterService) {
        this.oauthService.configure(authConfig);
        this.oauthService.loadDiscoveryDocumentAndLogin();
        this.oauthService.setupAutomaticSilentRefresh();
    ...

我已经从博客 post 中克隆并设置了提供的示例,并使用相同的 Azure 应用程序(租户和客户端 ID 等)对其进行了配置。 它在那里工作正常,我可以看到它在请求中将我的不记名令牌发送到 API

Screenshot of request header from request sent from the sample application 我注意到示例应用程序向 api 发送了两个请求,第一个请求提供不记名令牌,第二个请求是一个简单的 GET 请求。 Two requests in the sample application

与此同时,我的应用程序仅发送一个请求并且不包含不记名令牌: Request header from own application without bearer token 虽然上面的屏幕截图 returns 是 200,但这是因为本地 运行 后端不检查令牌。但正如您在屏幕截图中看到的那样,令牌并未传输。 这是来自已部署应用程序请求 运行 的另一个屏幕截图。由于设置而提供了更多信息,但令牌仍未发送。 Request header from own application (deployed version) without bearer token

关于问题可能是什么的任何想法?

OP在这里。 事实证明问题是因为“X-Frame-Options”响应 header 被设置为“DENY”。 header 如果设置为“拒绝”,则阻止不可见的框架被打开。 该实现在身份验证过程中使用 iFrame 进行静默重定向,这一关键部分已被阻止。

为了解决这个问题,我在 back-end 配置

中将其更改为“SAME ORIGIN”
        @Override
        protected void configure(HttpSecurity http) throws Exception {
        ...
        // global security configuration
        http.headers().frameOptions().sameOrigin().
        ...

希望这对将来可能偶然发现此问题的任何人有所帮助, 干杯并感谢那些帮助过的人, 狮子座