所以我有一个非常基本的最小API。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<IdentityDbContext>(options => options.UseInMemoryDatabase("AppDb"));
builder.Services.AddIdentityCore<User>()
.AddEntityFrameworkStores<IdentityDbContext>()
.AddApiEndpoints();
builder.Services.AddAuthentication().AddBearerToken(IdentityConstants.BearerScheme);
builder.Services.AddAuthorizationBuilder();
var app = builder.Build();
app.MapIdentityApi<User>();
app.MapGet("/test", (ClaimsPrincipal user) => $"Hello {user.Identity!.Name}").RequireAuthorization();
app.Run();
因此,我注册、登录,然后获得一个不记名令牌,我可以使用它来访问我的受保护/测试端点。
我希望当我重新启动应用程序并丢失所有数据(因为我使用
InMemoryDb
)时,我将无法再访问我的受保护端点,但我可以。
现在我不明白为什么身份服务在不验证
DbContext
中的用户时需要注册 DbContext
?
JWT 是一个独立的令牌,具有身份验证所需的所有信息。它包含三部分:标头、负载和签名。有效负载包括有关用户的声明,例如用户 ID、角色等。签名用于验证 JWT 的发送者是否是其声称的身份,并确保消息在此过程中没有更改。
当您使用 JWT 发送请求时,服务器会验证令牌的签名,如果有效,则它会信任有效负载中的声明,而无需再次检查数据库。这就是为什么在重新启动应用程序并丢失 InMemoryDb 中的所有数据后您仍然可以访问受保护的端点。
DbContext 不用于验证每个请求的令牌,它用于在用户登录时验证用户的凭据以及管理用户和角色。令牌验证由 JWT Bearer 中间件完成,该中间件验证令牌的签名和过期。
因此,在您的情况下,令牌仍然有效,因为它是在您重新启动应用程序之前颁发的。如果您想在重新启动应用程序时使令牌失效,则需要实施令牌撤销策略。这通常涉及将已发行的令牌存储在数据库中并检查它们对于每个请求是否仍然有效,这会增加应用程序的复杂性和开销。
如果您觉得有用,请点赞。 :)