【问题标题】:Can't catch exception thrown by JWT.无法捕获 JWT 抛出的异常。
【发布时间】:2018-05-30 19:53:05
【问题描述】:

我正在使用 asp.net core 2.0 制作一个小型 web api。我正在使用 JWT 来保护我的 api 端点。

这是我正在使用的 jwt 中间件this jwt bearer authentication

这是我的 Startup.cs 文件:

public class Startup
    {
        #region Properties

        /// <summary>
        ///     Instance stores configuration of application.
        /// </summary>
        public IConfigurationRoot Configuration { get; }

        #endregion

        #region Methods

        /// <summary>
        ///     Callback which is fired when application starts.
        /// </summary>
        /// <param name="env"></param>
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", true, true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        /// <summary>
        ///     This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {
            // Add entity framework to services collection.
            var sqlConnection = Configuration.GetConnectionString("SqlServerConnectionString");
            services.AddDbContext<RelationalDatabaseContext>(
                options => options.UseSqlServer(sqlConnection, b => b.MigrationsAssembly(nameof(Main))));

            // Injections configuration.
            services.AddScoped<IUnitOfWork, UnitOfWork>();
            services.AddScoped<DbContext, RelationalDatabaseContext>();
            services.AddScoped<IEncryptionService, EncryptionService>();
            services.AddScoped<IIdentityService, IdentityService>();
            services.AddScoped<ITimeService, TimeService>();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            // Requirement handler.
            services.AddScoped<IAuthorizationHandler, SolidAccountRequirementHandler>();
            services.AddScoped<IAuthorizationHandler, RoleRequirementHandler>();

            // Load jwt configuration from setting files.
            services.Configure<JwtConfiguration>(Configuration.GetSection(nameof(JwtConfiguration)));
            services.Configure<ApplicationSetting>(Configuration.GetSection(nameof(ApplicationSetting)));

            // Build a service provider.
            var serviceProvider = services.BuildServiceProvider();
            var jwtBearerSettings = serviceProvider.GetService<IOptions<JwtConfiguration>>().Value;

            // Cors configuration.
            var corsBuilder = new CorsPolicyBuilder();
            corsBuilder.AllowAnyHeader();
            corsBuilder.AllowAnyMethod();
            corsBuilder.AllowAnyOrigin();
            corsBuilder.AllowCredentials();

            // Add cors configuration to service configuration.
            services.AddCors(options => { options.AddPolicy("AllowAll", corsBuilder.Build()); });
            services.AddOptions();

            // This can be removed after https://github.com/aspnet/IISIntegration/issues/371
            var authenticationBuilder = services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme);

            authenticationBuilder.AddJwtBearer(o =>
            {
                // You also need to update /wwwroot/app/scripts/app.js
                o.SecurityTokenValidators.Clear();
                o.SecurityTokenValidators.Add(new JwtBearerValidator());
               o.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = jwtBearerSettings.Audience,
                    ValidIssuer = jwtBearerSettings.Issuer,
                    IssuerSigningKey = jwtBearerSettings.SigningKey
                };
            });


            #region Mvc builder

            // Construct mvc options.
            services.AddMvc(mvcOptions =>
            {
                mvcOptions.Filters.Add(new ApiExceptionFilter());
                ////only allow authenticated users
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)

#if !ALLOW_ANONYMOUS
                    .AddRequirements(new SolidAccountRequirement())
#endif
                    .Build();

                mvcOptions.Filters.Add(new AuthorizeFilter(policy));

            })
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });

#endregion
        }

        /// <summary>
        ///     This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        /// <param name="loggerFactory"></param>
        /// <param name="serviceProvider"></param>
        public void Configure(IApplicationBuilder app,
            IHostingEnvironment env,
            ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
        {
            // Enable logging.
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            // Use JWT Bearer authentication in the system.
            app.UseAuthentication();

            // Enable cors.
            app.UseCors("AllowAll");

            // Enable MVC features.
            app.UseMvc();
        }

#endregion
    }

通过使用这行代码:

mvcOptions.Filters.Add(new ApiExceptionFilter());

我可以捕获由 ASP.Net MVC 控制器、属性、...引发的异常 但我无法捕获 JWT 抛出的异常。

authenticationBuilder.AddJwtBearer(o =>
            {
                // You also need to update /wwwroot/app/scripts/app.js
                o.SecurityTokenValidators.Clear();
                o.SecurityTokenValidators.Add(new JwtBearerValidator());
                o.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = jwtBearerSettings.Audience,
                    ValidIssuer = jwtBearerSettings.Issuer,
                    IssuerSigningKey = jwtBearerSettings.SigningKey
                };

            });

谁能帮帮我?

谢谢,

【问题讨论】:

  • 查看新项目模板中的异常处理中间件。使用异常处理程序。您可以挂钩的 jwt 选项中还有一个 AuthenticationFailed 事件。
  • 我试过了,但只能捕获 MVC 异常。我知道 AuthenticationFailed ,但我想知道是否有全局捕获异常。
  • 你把它放在哪里了?它必须在 UseAuthentication 之前。我猜你不能使用重新执行版本,因为你会再次遇到相同的异常,你需要使用直接响应重载之一。
  • 您希望捕获哪些异常?例如,您想知道令牌何时验证失败吗?
  • 是的,我需要捕获 ISecurityTokenValidator 抛出的异常。

标签: asp.net-core asp.net-core-mvc asp.net-core-2.0 asp.net-core-webapi


【解决方案1】:

您可能想尝试使用全局异常处理方法为此类错误添加全局异常处理。查看作为ASP.NET Core 请求管道中的约定的异常处理包 - JosephWoodward/GlobalExceptionHandlerDotNet

【讨论】:

  • 正如描述所说,我认为它仅用于控制器异常日志记录。我认为它不适用于 Jwt 承载中间件
  • 先测试! TDD :)
  • 我试过了,但它不起作用。它只能捕获控制器内部抛出的异常。 :'(
猜你喜欢
  • 2021-09-02
  • 2011-04-05
  • 2015-09-23
  • 2013-08-02
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 2012-12-02
  • 2016-10-27
相关资源
最近更新 更多