ASP.NET Core Blazor集成IdentityServer实现可撤销API令牌咨询
你当前的环境是ASP.NET Core托管的Blazor应用,已配置AddIdentity<IdentityUser, IdentityRole>和AddApiAuthorization<IdentityUser, ApplicationDbContext>,结合你的需求(用户创建带过期/名称的可撤销API令牌、仅访问API、监控系统无OAuth支持),以下是具体解答:
1. ServerSideSessions是否适合你的场景?
不推荐用ServerSideSessions作为核心方案。ServerSideSessions主要用于管理用户的登录会话(比如基于Cookie的交互式会话),而你需要的是给监控系统用的API令牌(类似PAT),这类令牌的场景更适合用**Personal Access Token (PAT)**模式(即你找到的Duende示例方向)。
如果需要支持令牌撤销,ServerSideSessions不是必须的,而是需要结合令牌存储与验证机制:
- 若使用JWT格式令牌:需要额外实现黑名单(存储已撤销的JWT ID)或用Reference Token。
- 若使用Reference Token:IdentityServer会在服务器端存储令牌状态,此时可以复用ServerSideSessions的存储,但并非强制。
2. 密钥轮换后能否验证1年前的令牌?
分两种令牌类型讨论:
- JWT令牌:只要IdentityServer保留了签发该令牌时的旧签名密钥,就能验证。默认情况下,IdentityServer会将旧密钥持久化到存储(如数据库),只要旧密钥未被手动删除且令牌仍在有效期内,1年前的令牌可以正常验证。若旧密钥被清理,则无法验证。
- Reference Token:验证时直接查询服务器端存储的令牌状态,与密钥轮换无关,只要令牌未撤销、未过期,就能验证。
建议:若需要长期支持旧令牌验证,要么保留旧签名密钥至所有旧令牌过期,要么改用Reference Token。
3. 令牌撤销的实现方式
你用ITokenService生成的JWT令牌默认无内置撤销能力,可通过以下两种方案实现:
方案一:改用Reference Token
修改令牌生成逻辑,指定令牌类型为Reference:
var tokenRequest = new TokenCreationRequest { // 其他配置(audience、scopes、subject等) TokenType = OidcConstants.TokenTypes.Reference }; var token = await _tokenService.CreateTokenAsync(tokenRequest);
需要先在IdentityServer配置中启用Reference Token支持,此时IdentityServer会将令牌数据存储在服务器端(生产环境建议配置数据库/Redis存储)。撤销时调用IdentityServer的撤销端点即可,验证时会自动检查令牌状态。
方案二:JWT+黑名单机制
- 生成JWT时,将令牌的
jti(唯一ID)、过期时间、用户ID等元数据存入数据库。 - 实现撤销功能时,将目标令牌的
jti标记为已撤销(可设置自动清理过期的黑名单记录)。 - 在API的认证管道中添加自定义验证逻辑,检查当前令牌的
jti是否在黑名单中:
services.AddAuthentication() .AddJwtBearer(options => { options.Events = new JwtBearerEvents { OnTokenValidated = async context => { var jti = context.Principal.Claims.First(c => c.Type == JwtClaimTypes.JwtId).Value; var tokenStore = context.HttpContext.RequestServices.GetRequiredService<ITokenBlacklistStore>(); if (await tokenStore.IsRevokedAsync(jti)) { context.Fail("Token has been revoked"); } } }; });
4. 适配监控系统的最佳实践
结合你的需求,推荐流程:
- 在Blazor界面添加PAT管理页面,允许用户输入令牌名称、选择过期日期、指定API权限(仅分配API相关的scopes)。
- 生成令牌时,指定
audience为你的API资源,scopes为API所需权限,确保令牌仅能访问API端点。 - 将PAT的元数据(用户ID、名称、过期时间、jti、权限)持久化到数据库,用于后续撤销与审计。
- 撤销时,根据用户操作更新数据库状态,并同步到黑名单(JWT场景)或调用撤销端点(Reference Token场景)。
内容的提问来源于stack exchange,提问作者Marius Steinbach

