【问题标题】:AAD Token from SPA app works to call Nodejs API but not .Net WebAPI来自 SPA 应用程序的 AAD 令牌可以调用 Nodejs API,但不能调用 .Net WebAPI
【发布时间】:2017-10-20 20:36:01
【问题描述】:

我有一个使用 MSAL 从 AAD 获取令牌的 SPA 应用程序。因为 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 声明完全匹配。

【问题讨论】:

  • 您需要使用 MSAL 吗? ADAL 目前似乎更容易集成。

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


【解决方案1】:

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

【讨论】:

  • 谢谢,我会尝试一下。令人沮丧的是,使用 Nodejs/Passport 与 AAD 集成比与 MS 在 .Net 中自己的中间件集成更直观。
  • 努力让它工作。我的目标是.Net 4.6.1。 CustomValidatingJwtFormat 类派生自 JwtFormat 类,该类从 System.IdentityModel.Tokens 获取其 TokenValidationParameters。编译器说System.IdentityModel.Tokens 不包含TokenValidationParameters 的定义。 Microsoft.IdentityModel.Tokens 确实包含一个定义,但随后我收到错误,因为编译器无法从 Microsoft.IdentityModel.Tokens 转换为 System.IdentityModel.Tokens 任何解决此问题的方法?
  • 查看我的更新答案。不幸的是,我对它的工作原理并不深入
  • 感谢您的帮助。不幸的是,我在兜圈子。正如我所说,System.IdentityModel.TokensMicrosoft.IdentityModel.Tokens 库之间存在冲突。 Microsoft 库是我正在使用的 Microsoft.Owin 库的依赖项,而 System 库对于 JwtFormat 类来说是必需的。但是将它们都添加会导致冲突。可能不得不搬到 ADAL。
  • 您提到的类存在于nuget包“System.IdentityModel.Tokens.Jwt”中。这也是我们获得它的地方。
猜你喜欢
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多