代码之家  ›  专栏  ›  技术社区  ›  José Salgado vittore

ASP。NET Core 6 JWT承载令牌异常

  •  0
  • José Salgado vittore  · 技术社区  · 3 年前

    我正在尝试使用JWT承载令牌和google身份验证来实现对web API的身份验证。找到这个 answer 这很有帮助,但当它应该成功进行身份验证时,我得到了一个500,但有以下例外:

    系统NullReferenceException:对象引用未设置为实例 指一个物体。在 微软AspNetCore。认证。JWTBearner。JwtBearerHandler。handleAuthenticationAsync() 微软AspNetCore。诊断学。developerCeptionPageMiddleware: 错误:执行时发生未处理的异常 要求

    系统NullReferenceException:对象引用未设置为实例 指一个物体。在 微软AspNetCore。认证。JWTBearner。JwtBearerHandler。handleAuthenticationAsync() 在 微软AspNetCore。认证。JWTBearner。JwtBearerHandler。handleAuthenticationAsync() 在 微软AspNetCore。认证。AuthenticationHandler`1。验证teasync() 在 微软AspNetCore。认证。认证服务。AuthenticateTasync(HttpContext 上下文、字符串模式)位于 微软AspNetCore。认证。认证中间件。调用(HttpContext) (上下文)在 微软AspNetCore。诊断学。developerCeptionPageMiddleware。调用(HttpContext) (上下文)

    当令牌无效时,我会得到401响应。

     public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
                });
            });
    
            services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(o =>
                {
                    o.SecurityTokenValidators.Clear();
                    o.SecurityTokenValidators.Add(
                        new GoogleTokenValidator(
                            client_id
                            ));
                });
            
            services.AddScoped<PhotoService>();
            services.AddScoped<TagService>();
            services.AddScoped(_ => new BlobServiceClient(Configuration.GetConnectionString("AzureBlobStorage")));
            services.AddDbContext<Data.DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddControllers().AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
            });
            services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "rvc", Version = "v1" }); });
        }
    
     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                // app.UseSwagger();
                // app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "rvc v1"));
            }
    
            app.UseHttpsRedirection();
    
            if (env.IsProduction())
            {
                app.UseSpa(spa => { });
    
                app.UseFileServer(new FileServerOptions
                {
                    FileProvider = new PhysicalFileProvider(
                        Path.Combine(env.ContentRootPath, "client")),
                    EnableDefaultFiles = true
                });
            }
    
            app.UseRouting();
            app.UseCors();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    

    这是我的Google TokenValidator:

     public class GoogleTokenValidator : ISecurityTokenValidator
    {
        private readonly string _clientId;
        private readonly JwtSecurityTokenHandler _tokenHandler;
    
        public GoogleTokenValidator(string clientId)
        {
            _clientId = clientId;
            _tokenHandler = new JwtSecurityTokenHandler();
        }
    
        public bool CanValidateToken => true;
    
        public int MaximumTokenSizeInBytes { get; set; } = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;
    
        public bool CanReadToken(string securityToken)
        {
            return _tokenHandler.CanReadToken(securityToken);
        }
    
        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            validatedToken = null;
            try
            {
                validationParameters.ValidateIssuer = true;
                var payload = GoogleJsonWebSignature.ValidateAsync(securityToken, new GoogleJsonWebSignature.ValidationSettings() { Audience =  new[] { _clientId }}).Result; // here is where I delegate to Google to validate
            
                var claims = new List<Claim>
                    {
                        new Claim(ClaimTypes.NameIdentifier, payload.Name),
                        new Claim(ClaimTypes.Name, payload.Name),
                        new Claim(JwtRegisteredClaimNames.FamilyName, payload.FamilyName),
                        new Claim(JwtRegisteredClaimNames.GivenName, payload.GivenName),
                        new Claim(JwtRegisteredClaimNames.Email, payload.Email),
                        new Claim(JwtRegisteredClaimNames.Sub, payload.Subject),
                        new Claim(JwtRegisteredClaimNames.Iss, payload.Issuer),
                    };
    
                var principle = new ClaimsPrincipal();
                principle.AddIdentity(new ClaimsIdentity(claims, JwtBearerDefaults.AuthenticationScheme));
                return principle;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                throw;
            }
        }
    }
    
    0 回复  |  直到 3 年前
        1
  •  0
  •   José Salgado vittore    3 年前

    刚刚发现问题在validatedToken上为空。添加了以下内容,效果良好:

     (...)
     validatedToken = _tokenHandler.ReadJwtToken(securityToken);
     var principle = new ClaimsPrincipal();
     (...)