在 Net Core WebApi 后台上从前端验证 Azure Bearer Token。

问题描述 投票:0回答:1

目标:在前端使用 Microsoft 登录对话框登录 Azure AD 用户。将令牌附加到后端请求中。在后端验证令牌,以确保只有授权用户可以访问代码。棘手的部分:手动验证,因为它不是唯一的验证方式。

我已经成功登录并发送token,但在验证时我得到了这样的错误。IDX10511: Signature validation failed. Keys tried: ...

这是我目前所掌握的信息

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    RestrictedPageComponent
  ],
  imports: [
    HttpClientModule,
    MsalModule.forRoot({
      auth: {
        clientId: '<CLIENT ID>',
      }
    }, {
      consentScopes: [
        'user.read',
        'openid',
        'profile',
      ],
      protectedResourceMap: [
        ['https://localhost:44323/v1/login', ['user.read']], // frontend
        ['https://localhost:5001/api/Login', ['user.read']] // backend
      ]
    }),
    BrowserModule,
    AppRoutingModule
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MsalInterceptor,
      multi: true
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

登录.组件.ts

  login() {
    const loginRequest = { scopes: ['https://graph.microsoft.com/User.ReadWrite'] };
    this.authService.loginPopup(loginRequest);
  }

而这似乎可以正常工作。我可以通过微软登录进行登录,MsalInterceptor会将不记名标记添加到后端请求头中。

在后端,我现在只想验证token是否有效,用户是否被正确认证。

private JwtSecurityToken Validate(string token)
{
    var stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
    // also tried "https://login.microsoftonline.com/<TENANT ID>/v2.0/.well-known/openid-configuration"

    var openIdConnectConfigurationRetriever = new OpenIdConnectConfigurationRetriever();
    var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, openIdConnectConfigurationRetriever);

    var config = configManager.GetConfigurationAsync().Result;

    var validationParameters = new TokenValidationParameters
    {
        IssuerSigningKeys = config.SigningKeys,

        // just for now
        ValidateAudience = false,
        ValidateIssuer = false,
        ValidateLifetime = false
    };

    var tokenHandler = new JwtSecurityTokenHandler();
    IdentityModelEventSource.ShowPII = true;

    token = token.Replace("Bearer ", string.Empty); // weird - the token starts with "Bearer " and is not valid like this
    var result = tokenHandler.ValidateToken(token, validationParameters, out var jwt);

    return jwt as JwtSecurityToken;
}

在调用 tokenHandler.ValidateToken(... 我总是得到一个错误,如 IDX10511: Signature validation failed. Keys tried: ....我不知道我是否正确理解和使用了整个概念.我越是阅读关于Azure Bearer标记和验证的用法,就越是让我困惑。

我可以在 http:/jwt.io 但签名总是无效的。

后台可以在不传递任何共享秘籍或客户端id的情况下验证token吗?"一开始这个方法正确吗?"我不知道我是否用了正确的端点来调用前端和后端,以及不同的端点所扮演的角色是什么?

编辑:我不确定我是否使用了正确的端点来调用前端和后端,以及不同的端点所扮演的角色(例如:有租户id或没有)。如果有人能解释一下就好了。

BR马蒂亚斯

asp.net-core azure-active-directory microsoft-graph bearer-token
1个回答
2
投票

看起来你的前端正在获取微软Graph API的访问令牌,该令牌只适用于MS Graph API,而不是你的API,这些Graph API令牌的构建方式也很特殊,你不应该尝试验证它们。

相反,在你的前端,你需要为你的API指定作用域。

      consentScopes: [
        'your-api-client-id-or-app-id-uri/user_impersonation',
        'openid',
        'profile',
      ],
      protectedResourceMap: [
        ['https://localhost:44323/v1/login', ['user.read']], // frontend
        ['https://localhost:5001/api/Login', ['your-api-client-id-or-app-id-uri/user_impersonation']] // backend
      ]

为此,您需要在 Azure AD 中进入您的 API 的应用程序注册,进入 Expose an API 选项卡,并在那里添加一个作用域.然后您将完整的作用域 ID(其中包括您的 API 客户端 ID 或应用程序 ID URI + 作用域 ID),并在获取令牌时将其用作作用域.Azure AD 然后应该给您一个旨在为您的 API 提供的令牌。

如果你使用的是ASP.NET Core,你需要验证Azure AD令牌的最小配置是。

// In ConfigureServices
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.Authority = "https://login.microsoftonline.com/your-tenant-id";
        o.Audience = "your-app-client-id";
    });

// In Configure (between UseRouting and UseEndpoints)
app.UseAuthentication();
app.UseAuthorization();

现在,在某些情况下,如果您的API配置为在Azure AD中接收v1令牌,则令牌可能包含API客户端ID或应用程序ID URI.在这种情况下,您可以配置多个有效受众。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.Authority = "https://login.microsoftonline.com/your-tenant-id";
        o.TokenValidationParameters = new TokenValidationParameters
        {
            ValidAudiences = new[]
            {
                "your-api-client-id",
                "your-api-app-id-uri"
            }
        };
    })
© www.soinside.com 2019 - 2024. All rights reserved.