Skip to content

Fast.JwtBearer

逐成员 API、参数与返回参考

版本 3.5.41;目标 net8.0net9.0net10.0;依赖 Fast.Runtime 和对应目标的 ASP.NET Core JwtBearer 包。命名空间 Fast.JwtBearer

bash
dotnet add package Fast.JwtBearer

选择注册入口

入口注册内容
AddJwtBearerSetting(configuration, section = "JWTSettings")仅设置工具使用的选项,注册分布式内存缓存回退;另有选项回调重载
AddJwtBearerAuthentication(configuration, section = "JWTSettings")设置 Bearer 认证,适合自己管理授权流程;另有选项回调重载
AddJwtBearer(configuration, section = "JWTSettings")完整认证、策略处理器、发现的 IJwtBearerHandle,启用时增加 MVC 全局授权过滤器;另有选项回调重载

注册方法返回 IServiceCollection。完整宿主仍需要认证/授权中间件以及端点映射。

以下为消费端 Program.cs,使用 Microsoft.NET.Sdk.Web,目标选择本页列出的 .NET 8、9 或 10,并安装上方指定包。app.Run() 表示正常宿主启动;本次文档维护不会执行它。

csharp
using Fast.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddJwtBearer(builder.Configuration);

var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

示例要求宿主通过外部配置提供签名密钥,不内置可运行的公共密钥值。

JWTSettingsOptions 默认值

字段默认值 / 单位
ValidateIssuerSigningKeyValidateIssuerValidateAudienceValidateLifetimetrue
IssuerSigningKey必须显式配置,至少 32 个 UTF-8 字节;缺失或过短抛 InvalidOperationException
ValidIssuer / ValidAudienceFast.NET.API / Fast.NET.Client
ValidateAccessTokenfalse;失效标记检查需结合 SetExpiredToken
ClockSkew5 秒
TokenExpiredTime20 分钟
RefreshTokenExpireTime1440 分钟
RequireRefreshTokenCachetrue
AlgorithmJwtBearerAlgorithmEnum.HS256
Enabletrue;不等同于跳过密钥后配置校验

标准注册使用 AddDistributedMemoryCache() 作为未配置共享缓存时的回退;多实例刷新重放控制必须由共享 IDistributedCache 支持。Fast.Cache.ICacheIDistributedCache 是不同合同,不能只安装 Redis 封装就假定自动接通。

JwtBearerUtil

API返回与语义
GenerateToken(IDictionary<string, object> payload, long? expiredTime = null)返回访问令牌文本;expiredTime 单位分钟;会补充载荷字段,调用者不要假定字典保持原样
GenerateRefreshToken(string accessToken)返回与访问令牌关联的刷新令牌;空白或 JWT 段数不正确抛参数异常
GetJwtBearerToken(HttpContext, string headerKey = "Authorization", string tokenPrefix = "Bearer ")从请求头获取令牌;校验上下文、头名称和前缀
Validate/ValidateAsync返回包含 IsValidJsonWebTokenTokenValidationResult 的元组;需检查 IsValid
ReadJwtToken/SecurityReadJwtToken解析令牌文本,不等于完成签名、有效期和授权验证
Exchange/ExchangeAsync基于访问令牌与刷新令牌交换新令牌;参与缓存重放控制
AutoRefreshToken/AutoRefreshTokenAsync在授权流程中处理验证与自动刷新,返回是否通过
SetExpiredToken/SetExpiredTokenAsync将令牌标记失效;与对应校验设置共同生效
CreateTokenValidationParameters从设置构造认证库使用的验证参数

IJwtBearerHandle 包含 AuthorizeHandleAuthorizeFailHandlePermissionHandlePermissionFailHandle。成功检查返回 bool;失败始终记录 Fail。仅 MVC 过滤器上下文使用非 null 自定义结果生成 HTTP 401/403;其他资源由相应授权管线响应。实现按 Scoped 注册。PermissionAttributeAllowForbiddenAttribute 是该授权流程的元信息,不是独立认证器。

SignalR 的 access_token 查询参数只在已识别的 Hub 端点作为补充提取方式,并先保留已有提取逻辑;普通 HTTP 端点不因此接受查询令牌,也不因此取消授权要求。

已认证主体的令牌签发与校验

仅在应用已经验证用户身份之后调用签发方法;不能直接把未验证的请求字段当作可信身份。此类可与上面的 Program.cs 放在同一个 Web 项目,签名设置仍由宿主配置提供。

csharp
using Fast.JwtBearer;

public sealed record TokenPair(string AccessToken, string RefreshToken);

public sealed class TokenService
{
    public TokenPair IssueForAuthenticatedUser(string subject)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(subject);
        var payload = new Dictionary<string, object> { ["sub"] = subject };
        string access = JwtBearerUtil.GenerateToken(payload, expiredTime: 20);
        string refresh = JwtBearerUtil.GenerateRefreshToken(access);
        return new TokenPair(access, refresh);
    }

    public async Task<bool> IsValidAsync(string token)
    {
        var result = await JwtBearerUtil.ValidateAsync(token);
        return result.IsValid;
    }
}

有效期参数单位是分钟。不要记录返回的令牌,也不要把它放进 URL。ValidateAsync 的元组需要检查 IsValid;单纯 ReadJwtToken 只能读取内容,不能用于信任判断。刷新使用 ExchangeAsync(httpContext, expiredToken, refreshToken, ...),同时涉及失效策略和缓存防重放;多实例部署需要共享、具备原子消费能力的防重放存储器。退出时可调用 SetExpiredTokenAsync(httpContext, token),但仅当相应失效检查已启用时才能在后续校验中生效。

来源与验证

依据 注册实现选项工具 API。本轮仅源码核对,未创建真实令牌、访问缓存或启动认证宿主;新增片段未编译。

组合授权与刷新令牌安全

Fast 只对自身的 AppAuthorizeRequirement 调用 Succeed。角色、声明、第三方命名策略和显式 Fail() 不会被 AllowForbidden 或缺少自定义处理器的分支放行。非空 Fast 权限要求没有 IJwtBearerHandle 时明确拒绝;已有非 Fast 策略提供器和其他处理器在注册时保留。

AuthorizeFailHandle / PermissionFailHandle 返回自定义对象也不会清除失败状态。只有 MVC 过滤器上下文写入该对象;普通端点和 SignalR 由各自的授权管线处理失败。

AutoRefreshTokenAsynctrue 表示当前流程可以继续,不等于每次都签发了新令牌。自动刷新在同一个标准 ClaimsPrincipal 中更新已验证身份,并沿用 Bearer 的声明映射;无法安全原地更新的自定义 Principal 在消费刷新令牌前返回 false。刷新失败不应被当作业务成功。

多实例的一次性消费由 Fast.Runtime.IRefreshTokenReplayStore 表达。Fast.Cache 注册 Redis 的原子 NX+过期实现;只有进程内 MemoryDistributedCache 可以使用内存回退。其他 IDistributedCache 必须注册原子实现,不能依靠 Get 后 Set 声称防重放。自定义实现应在默认模块注册之后注册。

默认复用宽限为 0。同一刷新令牌只有一次消费权;显式设置正的 clockSkew 参数会允许首次消费后的兼容复用窗口,应理解它不是严格的一次性消费。缓存键使用令牌摘要,不保存明文令牌。验证失败、过期或缓存消费失败都不会签发访问令牌。

RequireRefreshTokenCache 默认为 true,缺少防重放实现时拒绝刷新。为兼容已有显式配置,设为 false 且没有注册实现时可以跳过消费校验,此时没有重放保护;已注册实现仍会执行校验。