来自 SPA 应用程序的 AAD 令牌可以调用 Nodejs API 但不能调用 .Net WebAPI

AAD Token from SPA app works to call Nodejs API but not .Net WebAPI

我有一个 SPA 应用程序,它使用 MSAL 从 AAD 获取令牌。因为 MSAL 使用 v2 端点并且因为 v2 端点当前不支持为自定义 API 颁发令牌,所以我将 ID 令牌传递到我的 api 并且基本上将我的 api 视为同一个应用程序。 (虽然这有点味道,但它确实有效——至少对于 Nodejs API)。

SPA 应用程序

let idToken = Msal.Storage('localStorage').getItem(Msal.Constants.idTokenKey);

this.http.configure(config => {
   config.withBaseUrl("http://localhost:3001/")
   config.withDefaults({headers: {'Authorization': 'Bearer ' + idToken}})
});

//Call API
this.http.fetch("account")
...

Node.js API

//Using express/passport
var BearerStrategy = require("passport-azure-ad").BearerStrategy;

var options = {
     identityMetadata: "https://login.microsoftonline.com/tenantid/.well-known/openid-configuration/",
     clientID: "xxxxxxx-xxxx-xxxxxxx-xxxxx",
     passReqtoCallback: false,
     validateIssuer: true,
     issuer: "http://login.microsoftonline.com/{tenantid}/v2.0"
};

app.get("/account",passport.authenticate('oauth-bearer',{session: false}),...

以上都有效。一旦用户通过 SPA 进行身份验证,令牌就会被传递并且对节点的调用 API 有效。

我现在正在尝试用 .Net WebAPI 替换 Nodejs API。我有以下内容:

Startup.cs

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
   new WindowsAzureActiveDirectoryBearerAuthenticationOptions
   {
      TokenValidationParameters = new TokenValidationParameters
      {
         //Same ID as used for ClientID in Nodejs
         ValidAudience = "xxxxxx-xxxxx-xxxxx-xxxxx",
         ValidIssuer = "https://login.microsoftonline.com/{tenantid}/v2.0",
         ValidateIssuer = true,
         AuthenticationType = "WebApi" //Tried both with and without this
      },
      Tenant = "{tenantid}"  //have tried both id and name
    }
)

AccountController.cs

[Authorize]
[Route("account")]
public IHttpActionResult AccountProfile(){
   //Get Account information
   ....

   return Ok(profile);
}

但是,当我将 SPA 应用程序指向调用 .Net api 时,我总是得到 Authorization has been denied for this request

有什么我遗漏的吗?

编辑

顺便说一句,我检查了正在使用的令牌。

我为 clientID (Nodejs) 和 ValidAudience (.Net) 使用的值与令牌中的 aud 声明完全匹配。 issuer (Nodejs) 和 ValidIssuer (.Net) 与令牌中的 iss 声明完全匹配。最后,在我插入 {tenantid} 的代码中的任何位置,那里的实际值与令牌中的 tid 声明完全匹配。

我们在从 ADAL 切换到 MSAL 时遇到了类似的问题,并通过使用类似 this Github project 的方法使其正常工作。具体看一下这些文件:

https://github.com/oktadeveloper/okta-oauth-aspnet-codeflow/blob/master/Api/Startup.cs https://github.com/oktadeveloper/okta-oauth-aspnet-codeflow/blob/master/Api/OpenIdConnectCachingSecurityTokenProvider.cs

更新:我们的 Startup.cs:

        var provider = new OpenIdConnectCachingSecurityTokenProvider(
            string.Format(bc2Instace, tenant, policyId));
        var jwt = new JwtFormat(clientId, provider);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
        {
            AccessTokenFormat = jwt,
        });