如何使 Identity Core 生成的访问令牌无效?

Posted

技术标签:

【中文标题】如何使 Identity Core 生成的访问令牌无效?【英文标题】:How can I invalidate access tokens generated by Identity Core? 【发布时间】:2021-11-28 06:26:24 【问题描述】:

我已经在我的 .Net5 应用程序上实现了 Identity Core,以使用 4 个端点处理登录、注销、注册和刷新。

当我调用注销端点并发送刷新令牌时,它会从数据库中删除刷新令牌,因此用户无法刷新访问令牌。 问题是我仍然可以使用访问令牌来调用我的应用程序的端点并获得授权,直到其定期到期。

我想知道是否有办法在注销后使访问令牌无效而无需等待到期。

这是我在启动时的 ConfigureService:

 public void ConfigureServices(IServiceCollection services)
        
            services.AddControllers();
            services.AddSwaggerGen(c =>
            
                c.SwaggerDoc("v1", new OpenApiInfo  Title = "AuthenticationAndAuthorizationAPI", Version = "v1" );
            );
            services.AddIdentityCore<User>(o =>
            
                o.User.RequireUniqueEmail = true;
                o.Password.RequireDigit = false;
                o.Password.RequireNonAlphanumeric = false;
                o.Password.RequireUppercase = false;
                o.Password.RequiredLength = 0;
            ).AddEntityFrameworkStores<AuthenticationDbContext>();

            AuthenticationConfiguration authenticationConfiguration = new();
            _configuration.Bind("Authentication", authenticationConfiguration);

            services.AddSingleton(authenticationConfiguration);

            services.AddEntityFrameworkNpgsql().AddDbContext<AuthenticationDbContext>(options =>
             options.UseNpgsql(_configuration.GetConnectionString("DBConnection")));

            services.AddSingleton<AccessTokenGenerator>();
            services.AddSingleton<RefreshTokenGenerator>();
            services.AddSingleton<RefreshTokenValidator>();
            services.AddScoped<Authenticator>();
            services.AddSingleton<TokenGenerator>();
            services.AddScoped<IRefreshTokenRepository, DatabaseRefreshTokenRepository>();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
            
                o.TokenValidationParameters = new TokenValidationParameters()
                
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authenticationConfiguration.AccessTokenSecret)),
                    ValidIssuer = authenticationConfiguration.Issuer,
                    ValidAudience = authenticationConfiguration.Audience,
                    ValidateIssuerSigningKey = true,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ClockSkew = TimeSpan.Zero
                ;
            );
        

【问题讨论】:

"当我调用注销端点并发送刷新令牌时,它会从数据库中删除刷新令牌,因此用户无法刷新访问令牌。问题是我仍然可以使用访问令牌调用我的应用程序的端点并获得授权,直到其正常到期。” - 您从数据库或访问令牌中删除刷新令牌?是否要使刷新令牌或访问令牌无效?你有错别字 我从数据库中删除了刷新令牌,因此我无法请求新的访问令牌,但最后一个令牌在到期之前仍然有效,我希望在注销时使最后一个访问令牌无效。 【参考方案1】:

您不能“使”JWT 令牌“无效” - 您有几个选择。

一些变通方法,例如缩短令牌到期时间以缩短攻击窗口或在应用程序注销时移除令牌客户端仍然保留“攻击者”事先窃取密钥的问题。

要强制真正的服务器端失效,您可以使用 lastLogoutTs 值对 JWT 令牌进行签名,该值会在每次注销时更新。用户注销后,他们的lastLogoutTs 值在数据库中发生更改,这意味着 JWT 令牌不再有效且无法验证访问权限。这显然意味着您在每次注销时都会访问数据库,但实际上并没有听起来那么糟糕,因为您可能会访问数据库以加载用户以将其注销。

或者,您可以在内存数据库中保留blocklist 表而不是额外字段,这允许您在 Redis、Memcached 等键上设置过期时间。该表将存储访问令牌已注销,尚未达到令牌到期日期的用户。例如,在 Redis 中,您可以使用 EXPIRE 自动删除访问令牌,同时速度也非常快(因为它是一个内存数据库)。

对于一个不能使用数据库的解决方案(想不出任何),JWT 不合适,像 OAuth 2.0 这样的东西会更好(最终,将注销逻辑卸载到谷歌、苹果等提供商) .).

【讨论】:

以上是关于如何使 Identity Core 生成的访问令牌无效?的主要内容,如果未能解决你的问题,请参考以下文章

如何撤销存储在 Identity Server 数据库中的 asp net core 中的刷新令牌

Asp.Net Core Identity 未正确验证令牌到期 [重复]

ASP.NET CORE Identity DataProtectionTokenProviderOptions 密码重置令牌无效

如何使用 Oauth2 和 chrome.identity 获取 Facebook 令牌

Identity Server 4 - 如何解决客户端注销后访问令牌仍然有效?

Asp.Net Core Identity 使用 JWT 中的哪些信息来将令牌授权为有效?