【问题标题】:.NET Core 3.1 SPA + web API with Azure AD error on Authorize.NET Core 3.1 SPA + Web API 与 Azure AD 授权错误
【发布时间】:2020-11-13 14:56:24
【问题描述】:

我正在尝试创建一个访问 .NET Core 3.1 Web Api 后端的 Angular 10 前端。它们都使用 MSAL 库在 Azure AD 下进行保护。我创建了 SPA 应用并使用 Visual Studio 2019 的 SPA Angular Template for Web Apps。在客户端应用程序上,我使用 msal-angular 登录并获取访问令牌。我关注了QuickstartTutorial,最后我尝试了Single Page App Scenario(使用隐式流程)。对于 Web API,我遵循 Single Page App Scenario 中的说明,并且我尝试过使用 Protected web API ScenarioWeb App that calls web APIs Scenario,但是当我尝试访问任何具有 Authorize 装饰器的 Web API 端点时,我得到了以下错误:System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token

还有其他人成功地创建了我想要做的事情(SPA 模板、Angular 10、.NET Core 3.1 Web API)吗?我做错了什么或错过了什么?

就我的问题而言,我的应用注册数据如下:

租户:
租户 ID: 'tttttttt-tttt-tttt-tttt-ttttttttttt'
域: 'notrealdomain .onmicrosoft.com'

客户端应用程序:
客户端 ID: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'

API 应用程序:
客户端 ID: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
应用程序 ID: 'api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/access_as_user'

我的令牌如下所示:

{
  "aud": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
  "iss": "https://login.microsoftonline.com/tttttttt-tttt-tttt-tttt-ttttttttttt/v2.0",
  "iat": 1595531437,
  "nbf": 1595531437,
  "exp": 1595535337,
  "aio": "ATQAy/8QAA01PbjYzolbeAAE6rlHrUQ5ndpD/CDAxneSI8BsXSdm3Sl7CBYWqoS+jyBUNtJ/Ovwe",
  "groups": [
    "gggggggg-gggg-gggg-gggg-gggggggggggg",
    "ffffffff-ffff-ffff-ffff-ffffffffffff"
  ],
  "name": "John Doe",
  "nonce": "hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh",
  "oid": "iiiiiiii-iiii-iiii-iiii-iiiiiiiiiiii",
  "preferred_username": "john@notrealdomain.onmicrosoft.com",
  "sub": "hrhuh3UtYWRmuT-JnNWuFhFYvWjbJFmegz7k2ay0RbI",
  "tid": "tttttttt-tttt-tttt-tttt-ttttttttttt",
  "uti": "PAkaSoPlaWi_vBYklUKtAA",
  "ver": "2.0"
}

app.module.ts

 @NgModule({
 declarations: [
 ... code ommited ...
 ],
 imports: [
 ... code ommited ...
 MsalModule.forRoot({
        auth: {
          clientId: 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
          authority: 'https://login.microsoftonline.com/tttttttt-tttt-tttt-tttt-ttttttttttt/',
          postLogoutRedirectUri: "https://localhost:44000/signout",
          redirectUri: "https://localhost:44000/",
        },
        cache: {
          cacheLocation: 'localStorage',
          storeAuthStateInCookie: isIE, // Set to true for Internet Explorer 11
        },
        framework: {
            unprotectedResources: ['https://localhost:44000/api/Unsecured'],
            protectedResourceMap: new Map([
              ['https://localhost:44375', ['api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/access_as_user']],
              ['https://graph.microsoft.com/v1.0/me', ['user.read']],
              ['api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', ['access_as_user']],
            ])
        },
      }, {
        popUp: false,
        consentScopes: [
            'user.read',
            'openid',
            'profile',
            'api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/access_as_user',
        ],
        extraQueryParameters: {}
      }),
 ... code ommited ...
 providers: [
     ... code ommited ...
     {
       provide: HTTP_INTERCEPTORS,
       useClass: MsalInterceptor,
       multi: true
     },

我在我的一个组件中使用以下方法登录,其中this.msalService 被注入为private msalService: MsalService

this.msalService.loginRedirect({
  scopes: [
      'api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/access_as_user',
    ]
});

在我的 Web API 上,我的 appsettings.json 文件中有以下配置:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "notrealdomain.onmicrosoft.com",
    "TenantId": "tttttttt-tttt-tttt-tttt-ttttttttttt",
    "ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "Audience": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
  },
... code ommited ...
}

最后,我的 StartUp.cs 看起来像这样:

    public void ConfigureServices(IServiceCollection services)
    {
        // Autenticación
        services.AddMicrosoftWebApiAuthentication(Configuration, "AzureAd");
        ... code ommited ...
    }
 
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ... code ommited ...
        app.UseRouting();

        // Autorización
        app.UseAuthentication();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
        });

        app.UseSpa(spa =>
        ... code ommited ...
    } 

【问题讨论】:

标签: asp.net angular azure msal msal.js


【解决方案1】:

确保您已授予 Azure AD 应用程序读取用户数据的权限:

另外,在清单中设置以下设置:

【讨论】:

  • 谢谢,蒂亚戈。我应该将此设置添加到哪个应用程序:客户端还是 API?在我的客户端应用程序注册中,我有“groupMembershipClaims”:“All, ApplicationGroup”和“oauth2AllowIdTokenImplicitFlow”:true,“oauth2AllowImplicitFlow”:true。
  • Thiago,我检查了 Web API 和客户端的清单,并更改了设置以反映您的建议,但没有运气。您还有其他建议吗?
  • 很多年前我就做过这个,我记得就是这样。如果有角色/组的声明,请检查 JWT 令牌。否则,令牌被截断的可能性很高,您需要手动查询 azure 广告
  • 谢谢,蒂亚戈。很有可能事情已经发生了变化。我在 Web API 端使用的 Microsoft.Identity.Web 库相对较新(2020 年初刚刚发布)。它取代了过去使用 Microsoft.AspNetCore.AzureAD.UI 完成的工作。但我会尝试手动阅读 JWT 并从那里查询 azure 广告。希望其他人以更直接的方式做到这一点。
猜你喜欢
  • 2020-08-02
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2017-01-04
  • 2020-06-28
  • 2018-11-19
  • 2020-10-27
  • 2018-06-05
相关资源
最近更新 更多