You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Angular2触发的WebApi1中调用受保护的WebApi2并获取Bearer Token

在WebApi1中调用受保护的WebApi2:获取Bearer令牌的方案

首先,你的场景是典型的用户上下文下的服务间调用——用户已通过Angular应用完成认证,WebApi1需要代表该用户调用另一个受保护的WebApi2。下面分两种常见场景给出具体实现方案:


方案1:直接转发Angular传来的访问令牌(简单场景)

如果你的WebApi1的访问令牌本身已经包含了访问WebApi2所需的权限(即令牌的scope字段包含WebApi2的授权范围),那么最直接的方式就是转发这个令牌给WebApi2。

实现步骤:

  1. 从WebApi1的请求中提取令牌
    当Angular调用WebApi1时,会在请求头里带上Authorization: Bearer {token}(通常你已经用Angular的HttpInterceptor自动添加了这个头)。在WebApi1中,你可以直接从请求上下文获取这个令牌:
    // 以ASP.NET Core为例
    var accessToken = await HttpContext.GetTokenAsync("access_token");
    
  2. 用转发的令牌调用WebApi2
    把提取到的令牌添加到调用WebApi2的请求头中:
    using var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    var response = await client.GetAsync("https://your-webapi2-url/api/your-resource");
    

注意事项:

  • 这个方案仅适用于原令牌已被授权访问WebApi2的情况,否则WebApi2会返回403 Forbidden。
  • 确保原令牌的aud(受众)包含WebApi2的标识,或者身份提供者支持令牌的多受众访问。

方案2:使用On-Behalf-Of(OBO)流获取专用令牌(推荐场景)

如果WebApi1的令牌没有访问WebApi2的权限,或者你希望遵循最小权限原则(不给WebApi1过度授权),那么应该使用OBO流——让WebApi1拿着用户的原令牌,向身份提供者请求一个专门用于访问WebApi2的新令牌。

实现步骤:

  1. 提前配置身份提供者

    • 在你的身份提供者(比如IdentityServer4、Azure AD等)中,为WebApi1注册一个客户端(机密客户端,因为服务间调用需要信任)。
    • 给WebApi1授予“代表用户访问WebApi2”的权限(即添加WebApi2的scope到WebApi1的授权列表中)。
  2. 在WebApi1中发起OBO令牌请求
    先提取Angular传来的原令牌,然后向身份提供者的令牌端点请求新令牌:

    // 先安装IdentityModel包(用于简化OAuth2操作)
    using IdentityModel.Client;
    
    // 1. 获取身份提供者的元数据
    var client = new HttpClient();
    var disco = await client.GetDiscoveryDocumentAsync("https://your-identity-provider-url");
    if (disco.IsError) throw new Exception($"Discovery failed: {disco.Error}");
    
    // 2. 提取Angular传来的原令牌
    var originalToken = await HttpContext.GetTokenAsync("access_token");
    
    // 3. 发起OBO令牌请求
    var tokenResponse = await client.RequestTokenAsync(new TokenRequest
    {
        Address = disco.TokenEndpoint,
        GrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer",
        ClientId = "webapi1-client-id", // 你在身份提供者注册的WebApi1客户端ID
        ClientSecret = "webapi1-client-secret", // 客户端密钥(机密客户端必填)
        Parameters =
        {
            { "token", originalToken }, // 用户的原访问令牌
            { "scope", "webapi2-required-scope" }, // WebApi2需要的权限范围
            { "resource", "webapi2-audience" } // 如果是Azure AD,需要指定WebApi2的受众标识
        }
    });
    
    if (tokenResponse.IsError) throw new Exception($"Token request failed: {tokenResponse.Error}");
    
    // 4. 使用新令牌调用WebApi2
    using var webApi2Client = new HttpClient();
    webApi2Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
    var response = await webApi2Client.GetAsync("https://your-webapi2-url/api/your-resource");
    

注意事项:

  • OBO流是专门为“服务代表用户调用其他服务”设计的,安全性更高,权限更可控。
  • 确保原令牌是访问令牌(不是ID令牌),因为ID令牌不能用于OBO流。
  • 身份提供者需要支持OBO流(主流的OAuth2/OIDC实现都支持,比如IdentityServer4、Azure AD、Okta等)。

额外提示

  • 不管用哪种方案,WebApi1都要先验证原令牌的有效性(比如签名是否合法、是否过期、受众是否正确),避免使用伪造的令牌。在ASP.NET Core中,只要你正确配置了JWT认证中间件,这个验证会自动完成。
  • Angular中存储在localStorage的令牌,一定要通过HttpInterceptor自动添加到所有对WebApi1的请求头中,确保WebApi1能拿到令牌。

内容的提问来源于stack exchange,提问作者Mukil Deepthi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:02:39