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

时间:2017-10-20 20:36:01

标签: asp.net-web-api azure-active-directory msal

我有一个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进行身份验证,就会传递令牌并调用Node 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声明完全匹配。

1 个答案:

答案 0 :(得分:0)

从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,
        });