You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.5 KiB
217 lines
5.5 KiB
3 months ago
|
# JWT 服务注册指南
|
||
|
|
||
|
## 服务注册概览
|
||
|
|
||
|
JWT 相关的服务注册主要分布在两个位置:
|
||
|
1. `Program.cs` - Web API 层的服务注册
|
||
|
2. `DependencyInjection.cs` - 基础设施层的服务注册
|
||
|
|
||
|
## 1. 基础设施层注册 (DependencyInjection.cs)
|
||
|
|
||
|
### 1.1 JWT 配置注册
|
||
|
```csharp
|
||
|
// 配置 JWT 选项
|
||
|
services.Configure<JwtOptions>(configuration.GetSection(JwtOptions.SectionName));
|
||
|
services.AddSingleton<IConfigureOptions<JwtBearerOptions>, JwtBearerOptionsSetup>();
|
||
|
services.AddScoped<IJwtProvider, JwtProvider>();
|
||
|
```
|
||
|
|
||
|
说明:
|
||
|
- `Configure<JwtOptions>`: 从配置文件加载 JWT 配置
|
||
|
- `JwtBearerOptionsSetup`: 配置 JWT Bearer 认证选项
|
||
|
- `JwtProvider`: 实现 JWT 令牌的生成和验证
|
||
|
|
||
|
### 1.2 密钥管理服务注册
|
||
|
```csharp
|
||
|
// 注册密钥轮换服务
|
||
|
services.AddSingleton<IKeyRotationService, KeyRotationService>();
|
||
|
services.AddHostedService<KeyRotationBackgroundService>();
|
||
|
```
|
||
|
|
||
|
说明:
|
||
|
- `KeyRotationService`: 管理 JWT 密钥的生命周期
|
||
|
- `KeyRotationBackgroundService`: 后台服务,定期执行密钥轮换
|
||
|
|
||
|
### 1.3 认证服务注册
|
||
|
```csharp
|
||
|
// 配置JWT认证
|
||
|
services.AddAuthentication(options =>
|
||
|
{
|
||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
})
|
||
|
.AddJwtBearer();
|
||
|
|
||
|
services.AddAuthorization();
|
||
|
```
|
||
|
|
||
|
说明:
|
||
|
- 设置默认认证方案为 JWT Bearer
|
||
|
- 启用授权服务
|
||
|
|
||
|
## 2. Web API 层注册 (Program.cs)
|
||
|
|
||
|
### 2.1 JWT 配置注册
|
||
|
```csharp
|
||
|
// 配置JWT认证
|
||
|
builder.Services.Configure<JwtOptions>(builder.Configuration.GetSection("JwtOptions"));
|
||
|
builder.Services.AddSingleton<IConfigureOptions<JwtBearerOptions>, JwtBearerOptionsSetup>();
|
||
|
```
|
||
|
|
||
|
### 2.2 认证服务注册
|
||
|
```csharp
|
||
|
builder.Services.AddAuthentication(options =>
|
||
|
{
|
||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
})
|
||
|
.AddJwtBearer();
|
||
|
```
|
||
|
|
||
|
### 2.3 Swagger 配置
|
||
|
```csharp
|
||
|
builder.Services.AddSwaggerGen(options =>
|
||
|
{
|
||
|
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||
|
{
|
||
|
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
|
||
|
Name = "Authorization",
|
||
|
In = ParameterLocation.Header,
|
||
|
Type = SecuritySchemeType.ApiKey,
|
||
|
Scheme = "Bearer"
|
||
|
});
|
||
|
|
||
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||
|
{
|
||
|
{
|
||
|
new OpenApiSecurityScheme
|
||
|
{
|
||
|
Reference = new OpenApiReference
|
||
|
{
|
||
|
Type = ReferenceType.SecurityScheme,
|
||
|
Id = "Bearer"
|
||
|
}
|
||
|
},
|
||
|
Array.Empty<string>()
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
```
|
||
|
|
||
|
## 3. 服务注册优化建议
|
||
|
|
||
|
### 3.1 避免重复注册
|
||
|
目前存在重复注册的问题:
|
||
|
1. JWT 配置在两个地方都进行了注册
|
||
|
2. 认证服务在两个地方都进行了配置
|
||
|
|
||
|
建议优化方案:
|
||
|
```csharp
|
||
|
// 在 DependencyInjection.cs 中统一注册
|
||
|
public static IServiceCollection AddJwtServices(
|
||
|
this IServiceCollection services,
|
||
|
IConfiguration configuration)
|
||
|
{
|
||
|
// 配置 JWT 选项
|
||
|
services.Configure<JwtOptions>(configuration.GetSection(JwtOptions.SectionName));
|
||
|
|
||
|
// 注册 JWT 服务
|
||
|
services.AddSingleton<IConfigureOptions<JwtBearerOptions>, JwtBearerOptionsSetup>();
|
||
|
services.AddScoped<IJwtProvider, JwtProvider>();
|
||
|
services.AddSingleton<IKeyRotationService, KeyRotationService>();
|
||
|
services.AddHostedService<KeyRotationBackgroundService>();
|
||
|
|
||
|
// 配置认证
|
||
|
services.AddAuthentication(options =>
|
||
|
{
|
||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||
|
})
|
||
|
.AddJwtBearer();
|
||
|
|
||
|
services.AddAuthorization();
|
||
|
|
||
|
return services;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 3.2 配置文件结构
|
||
|
建议的 JWT 配置结构:
|
||
|
```json
|
||
|
{
|
||
|
"JwtOptions": {
|
||
|
"SecretKey": "your-secret-key",
|
||
|
"Issuer": "your-issuer",
|
||
|
"Audience": "your-audience",
|
||
|
"ExpiryMinutes": 15,
|
||
|
"RefreshTokenExpiryDays": 7,
|
||
|
"ClockSkewMinutes": 5,
|
||
|
"KeyRotationDays": 30,
|
||
|
"MinKeyLength": 64
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## 4. 中间件配置
|
||
|
|
||
|
### 4.1 认证中间件
|
||
|
```csharp
|
||
|
// 启用认证中间件
|
||
|
app.UseAuthentication();
|
||
|
|
||
|
// 启用授权中间件
|
||
|
app.UseAuthorization();
|
||
|
```
|
||
|
|
||
|
### 4.2 HTTPS 重定向
|
||
|
```csharp
|
||
|
// 启用 HTTPS 重定向
|
||
|
app.UseHttpsRedirection();
|
||
|
```
|
||
|
|
||
|
## 5. 使用建议
|
||
|
|
||
|
1. **配置管理**
|
||
|
- 使用强类型配置
|
||
|
- 集中管理配置项
|
||
|
- 避免硬编码敏感信息
|
||
|
|
||
|
2. **服务注册**
|
||
|
- 使用扩展方法组织服务注册
|
||
|
- 避免重复注册
|
||
|
- 遵循依赖注入最佳实践
|
||
|
|
||
|
3. **安全配置**
|
||
|
- 启用 HTTPS
|
||
|
- 配置适当的 CORS 策略
|
||
|
- 实现完整的认证和授权
|
||
|
|
||
|
4. **开发体验**
|
||
|
- 配置 Swagger 文档
|
||
|
- 提供详细的错误信息
|
||
|
- 实现适当的日志记录
|
||
|
|
||
|
## 6. 常见问题
|
||
|
|
||
|
1. **配置加载失败**
|
||
|
- 检查配置文件路径
|
||
|
- 验证配置节点名称
|
||
|
- 确保配置值格式正确
|
||
|
|
||
|
2. **认证失败**
|
||
|
- 检查令牌格式
|
||
|
- 验证密钥配置
|
||
|
- 确认过期时间设置
|
||
|
|
||
|
3. **密钥轮换问题**
|
||
|
- 检查轮换间隔设置
|
||
|
- 验证密钥生成逻辑
|
||
|
- 确保缓存正确更新
|
||
|
|
||
|
4. **性能问题**
|
||
|
- 优化令牌验证
|
||
|
- 使用适当的缓存策略
|
||
|
- 控制令牌大小
|