2017-10-04 17 views
0

Jwt認証に関する問題に直面しています。ASP.NET Core 2 Jwt Auth with Azure B2C // IDX10500:署名の検証に失敗しました。署名を検証するためのセキュリティキーがありません

私はSPA App(Vue-App)にもサービスするASP.NET Core 2 WepApiを持っています。SPA Appは、MicrosoftのMSAL.jsライブラリを使用してAzure B2Cからトークンを取得します。私は私が次のエラーを取得認証する必要がありWEBAPIヒットすると

は:ブラウザで

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1] 
     Failed to validate the token [MyTokenHere] 
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10500: Signature validation failed. No security keys were provided to validate the signature. 
    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: IDX10500: Signature validation failed. No security keys were provided to validate the signature. 

を私は401

GET http://localhost:51420/api/values 401 (Unauthorized) 

私はサンプルと非常に同じ問題に直面してもらいますアプリケーションはここに提供An ASP.NET Core web API with Azure AD B2C(その黄色と)

ここは私のStartup.csです

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.AspNetCore.Authentication.JwtBearer; 
using Microsoft.AspNetCore.Builder; 
using Microsoft.AspNetCore.Hosting; 
using Microsoft.AspNetCore.Http; 
using Microsoft.AspNetCore.SpaServices.Webpack; 
using Microsoft.Extensions.DependencyInjection; 
using Microsoft.IdentityModel.Tokens; 
using VueTemplate.SignalR; 

namespace VueTemplate 
{ 
    public class Startup 
    { 
     public string Authority { get; set; } = "https://login.microsoftonline.com/tfp/[MyB2CTenant]/[MyPolicy]/v2.0/"; 

     public string ClientId { get; set; } = [MyApplicationId]; 


     // This method gets called by the runtime. Use this method to add services to the container. 
     // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 
     public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddMvc(); 
      services.AddSignalR(); 
      services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 
      .AddJwtBearer(options => new JwtBearerOptions() { 
       Authority = Authority, 
       Audience = ClientId, 
       Events = new JwtBearerEvents() { OnAuthenticationFailed = AuthenticationFailed, } 
      }); 
     } 

     // 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.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions() { 
        HotModuleReplacement = true 
       }); 
      } 
      else { 
       app.UseExceptionHandler("/Home/Error"); // TODO Create Error page 
      } 

      app.UseAuthentication(); 

      app.UseStaticFiles(); 

      app.UseSignalR(routes => { 
       routes.MapHub<ChatHub>("Hub/Chat"); 
      }); 

      app.UseMvc(routes => { 
       routes.MapRoute(
        name: "default", 
        template: "{controller=Home}/{action=Index}" 
       ); 

       routes.MapSpaFallbackRoute(
        name: "spa-fallback", 
        defaults: new { controller = "Home", action = "Index" } 
       ); 
      }); 
     } 

     private Task AuthenticationFailed(AuthenticationFailedContext arg) 
     { 
      // For debugging purposes only! 
      var s = $"AuthenticationFailed: {arg.Exception.Message}"; 
      arg.Response.ContentLength = s.Length; 
      arg.Response.Body.Write(Encoding.UTF8.GetBytes(s), 0, s.Length); 
      return Task.FromResult(0); 
     } 
    } 
} 

ValuesController.cs

using Microsoft.AspNetCore.Authorization; 
using Microsoft.AspNetCore.Mvc; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 

namespace VueTemplate.Controllers 
{ 
    [Authorize] 
    [Route("api/[controller]/")] 
    public class ValuesController : Controller 
    { 
     [HttpGet] 
     public IActionResult Get() { 
      return Ok(new int[] { 1, 2, 3, 4 }); 
     } 
    } 
} 

任意の考え?私はセキュリティキーを提供する必要がありますか?どこでAzure B2Cでそれを見つけるのですか?

+0

あなたはこれを試してみました[サンプル](https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapi /blob/master/B2C-WebApi/Startup.cs#LC52)?バックエンドのサンプルを使ってSPAを稼働させることができるのだろうかと思います。 – spottedmahn

+0

はい、この例を試しました。私はすでに私の質問でそれを参照しています。サンプルを私のSPAの有無にかかわらず取得することができません。サンプルがあなたに適していますか? – VSDekar

+0

セキュリティキーを提供する必要はありません。ライブラリはキーを動的に取得し、検証を実行します。 [参考文献1](https://stackoverflow.com/questions/45623178/wheres-the-key-for-my-azure-ad-b2c-token) [参考資料2 - トークン検証](https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-tokens#token-validation) – spottedmahn

答えて

3

私は私の問題の解決策を見つけました。

AddJwtBearer()メソッドを設定する正しい方法は、既に提供されているオプションオブジェクトを使用し、新しいものを作成しないことです。

悪い:

.AddJwtBearer(option => new JwtBearerOptions // <--- Evil 
       { 
        Authority = string.Format("https://login.microsoftonline.com/tfp/{0}/{1}/v2.0/", 
        Configuration["Authentication:AzureAd:Tenant"], Configuration["Authentication:AzureAd:Policy"]), 
        Audience = Configuration["Authentication:AzureAd:ClientId"], 
        Events = new JwtBearerEvents 
        { 
         OnAuthenticationFailed = AuthenticationFailed 
        }, 
       }); 

グッド:

.AddJwtBearer(options => { 
        options.Authority = string.Format("https://login.microsoftonline.com/tfp/{0}/{1}/v2.0/", Configuration["Authentication:AzureAd:Tenant"], Configuration["Authentication:AzureAd:Policy"]); 
        options.Audience = Configuration["Authentication:AzureAd:ClientId"]; 
        options.Events = new JwtBearerEvents { 
         OnAuthenticationFailed = AuthenticationFailed 
        }; 
       }); 
関連する問題