代码之家  ›  专栏  ›  技术社区  ›  VSDekar

ASP。NET Core 2 Jwt Auth with Azure B2C//IDX10500:签名验证失败。没有提供安全密钥来验证签名

  •  0
  • VSDekar  · 技术社区  · 7 年前

    当我点击需要授权的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 (带着他们的tanant)

    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);
            }
        }
    }
    

    值控制器。反恐精英

    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的哪里可以找到它?

    1 回复  |  直到 7 年前
        1
  •  3
  •   VSDekar    7 年前

    我已经找到了解决我问题的办法。

    配置的正确方法 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
                        };
                    });