ASP.net Core 2.0 AzureAd Bearer JWT-Token Auth 在验证签名时不会失败

Posted

技术标签:

【中文标题】ASP.net Core 2.0 AzureAd Bearer JWT-Token Auth 在验证签名时不会失败【英文标题】:ASP.net Core 2.0 AzureAd Bearer JWT-Token Auth not fail on validate signature 【发布时间】:2018-07-07 07:48:04 【问题描述】:

我有两个应用程序一个 Web 应用程序 (Web-UI) 和一个 Web api。 首先,我在 Web-UI 中实现了使用 Azure AD 的身份验证。 这两个应用程序都在 Azure 中注册并相互推动。--

首先是我的配置

tenant: '99c7da52-56fc-49ca-aa95-111111111111',
clientId: '6b0a79eb-0e0d-4a00-9652-111111111111

登录就像我成功获得令牌一样的魅力。它看起来像下面这样:

Header

  "typ": "JWT",
  "nonce": "AQABAAAAAABHh4kmS_aKT5XrjzxRAtHzn-GbcsmT8MupNislUn7vudKeuWR-HgBEd2ceWxQ7UulHr-uachkZA9cWVIj5ah3yzI68oYKyzc-QdynAf3a5DSAA",
  "alg": "RS256",
  "x5t": "z44wMdHu8wKsumrbfaK98qxs5YI",
  "kid": "z44wMdHu8wKsumrbfaK98qxs5YI"

Payload 

  "aud": "00000003-0000-0000-c000-000000000000",
  "iss": "https://sts.windows.net/99c7da52-56fc-49ca-aa95-8f7fb09c995e/",
  "iat": 1517145610,
  "nbf": 1517145610,
  "exp": 1517149510,
  "acr": "1",
  "aio": "ATQAy/8GAAAAYOQzoNWpu5XcyTPibpz9lnb/bMGY3H4iTdEdz/zvWwrTt1mvvWiLToaNPYZwHsBD",
  "amr": [
    "pwd",
    "mfa"
  ],
  "app_displayname": "My Project",
  "appid": "6b0a79eb-0e0d-4a00-9652-3098cc95804f",
  "appidacr": "0",
  "e_exp": 262800,
  "family_name": "XXXXXXXXX",
  "given_name": "XXXXXXXXXX",
  "ipaddr": "93.245.65.135",
  "name": "Myname, Firstname",
  "oid": "1a4d0d0f-8137-4c1d-aa34-2cccf10f8206",
  "platf": "3",
  "puid": "100300008AAF747A",
  "scp": "Directory.Read.All email Group.Read.All profile User.Read User.Read.All User.ReadBasic.All",
  "sub": "IBv63_IIq4zpkv_UlVwaxmAm0RP3d17xq4hKil4HRD0",
  "tid": "89c7da52-56fc-49ca-aa95-8f7fb09c995e",
  "unique_name": "XXXXXXXXXXXXXXX",
  "upn": "XXXXXXXXXXXXXXX",
  "uti": "LVVtGIEcXUuEofBatBYVAA",
  "ver": "1.0"

我删除了个人信息。所以现在我对我的 Web.Api 使用令牌,它包含以下设置:

  "AzureAdB2C": 
"Instance": "https://login.microsoftonline.com/common",
"ClientId": "f5afed6b-e09c-4c7d-90cc-222222222222",
"Domain": "myhost.de"

我的启动文件看起来:

public class Startup

    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public IConfiguration Configuration  get; 

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    
        services.AddAuthentication(sharedOptions =>
        
            sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        )
        .AddAzureAdBearer(options => Configuration.Bind("AzureAdB2C", options));
        services.AddMvc();
    

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();          
        

        app.UseAuthentication();
        app.UseMvc();
    

当我使用 Postman 使用与“Bearer tokenstring”相同的令牌调用 api 时,不会。它告诉我 401 未授权。

在控制台的调试日志中出现了这个:

    Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.X509SecurityKey , KeyId: z44wMdHu8wKsumrbfaK98qxs5YI
'.
Exceptions caught:
 ''.
token: '"alg":"RS256","typ":"JWT","nonce":"AQABAAAAAABHh4kmS_aKT5XrjzxRAtHzn-GbcsmT8MupNislUn7vudKeuWR-HgBEd2ceWxQ7UulHr-uachkZA9cWVIj5ah3yzI68oYKyzc-QdynAf3a5DSAA","x5t":"z44wMdHu8wKsumrbfaK98qxs5YI","kid":"z44wMdHu8wKsumrbfaK98qxs5YI"."aud":"00000003-0000-0000-c000-000000000000","iss":"https://sts.windows.net/99c7da52-56fc-49ca-aa95-8f7fb09c995e/","iat":1517145610,"nbf":1517145610,"exp":1517149510,"acr":"1","aio":"ATQAy/8GAAAAYOQzoNWpu5XcyTPibpz9lnb/bMGY3H4iTdEdz/zvWwrTt1mvvWiLToaNPYZwHsBD","amr":["pwd","mfa"],"app_displayname":"Project Avalon Dev","appid":"6b0a79eb-0e0d-4a00-9652-3098cc95804f","appidacr":"0","e_exp":262800,"family_name":"XXXXX","given_name":"Sascha Peter","ipaddr":"93.245.65.135","name":"XXXX","oid":"da4d0d0f-8137-4c1d-aa34-2cccf10f8206","platf":"3","puid":"100300008AAF747A","scp":"Directory.Read.All email Group.Read.All profile User.Read User.Read.All User.ReadBasic.All","sub":"IBv63_IIq4zpkv_UlVwaxmAm0RP3d17xq4hKil4HRD0","tid":"99c7da52-56fc-49ca-aa95-8f7fb09c995e","unique_name":"XXXXX","upn":"xxxxxxx","uti":"LVVtGIEcXUuEofBatBYVAA","ver":"1.0"'.
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__6.MoveNext()
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7]
      Bearer was not authenticated. Failure message: IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.X509SecurityKey , KeyId: z44wMdHu8wKsumrbfaK98qxs5YI
      '.
Exceptions caught:
 ''.
token: '"alg":"RS256","typ":"JWT","nonce":"AQABAAAAAABHh4kmS_aKT5XrjzxRAtHzn-GbcsmT8MupNislUn7vudKeuWR-HgBEd2ceWxQ7UulHr-uachkZA9cWVIj5ah3yzI68oYKyzc-QdynAf3a5DSAA","x5t":"z44wMdHu8wKsumrbfaK98qxs5YI...........

我的 webapi 项目的项目文件如下:

    <Project Sdk="Microsoft.NET.Sdk.Web">

      <PropertyGroup>
        <TargetFramework>netcoreapp2.0</TargetFramework>
        <UserSecretsId>aspnet-Portal.Api-B6631B80-5958-40CC-A783-2E86D5ADA6B5</UserSecretsId>
      </PropertyGroup>

      <ItemGroup>
        <Folder Include="wwwroot\" />
      </ItemGroup>

      <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
      </ItemGroup>

      <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
        <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
      </ItemGroup>

    </Project>

我不知道这个ist有什么问题。我错过了什么吗?我的代码中有错误吗?

【问题讨论】:

【参考方案1】:

aspnetcore jwt 承载实现无法验证标头中带有随机数的令牌,而这需要特殊处理。您尝试验证的令牌适用于 microsoft graph api,而不是您的应用程序。

如果您请求https://login.microsoftonline.com/common/oauth2/authorize?resource=APPID,您可以为您的应用获取令牌

我还能够验证资源/api https://graph.windows.net(而不是 https://graph.microsoft.com)的令牌,因为此令牌不包含随机数,但根据微软的说法,此 api 已过时,不应使用 (https://dev.office.com/blogs/microsoft-graph-or-azure-ad-graph) .

阅读更多: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609

【讨论】:

非常感谢这是问题所在。我使用了错误的应用程序 ID。 谢谢!我浪费了一天的大部分时间试图弄清楚为什么我的应用程序无法验证来自 graph.microsoft.com 的令牌,而它在使用 graph.windows.net 时运行良好。 “这需要特殊处理”对于编程建议来说似乎很模糊。我认为底线是该事物中的签名是在与附加到签名的标头不同的事物上计算的。原始签名的东西有 header.nonce = NONCE。附加的标头有 header.nonce = SHA256(nonce)。在不知道原始 nonce 的情况下无法确认 sig。要验证,您需要:拆分部分,解码 hdr,将 nonce 值设置为 hdr,重新编码,按点连接部分,然后验证。

以上是关于ASP.net Core 2.0 AzureAd Bearer JWT-Token Auth 在验证签名时不会失败的主要内容,如果未能解决你的问题,请参考以下文章

如何将 AzureAD 和 AzureADBearer 添加到 asp.net core 2.2 web api

Azure AD 与 ASP.NET Core MVC 中的标识

Azure AD 限制整个 ASP.NET Core API

ASP.NET Core 2.2 中的 Azure AD 身份验证

使用 Azure AD 的 Asp.net core mvc 基于角色的授权

如何在 ASP.NET Core Web API 中添加两个不同的令牌