Security in TaskHub.Shared covers authentication (who is the caller?), authorization (what may they do?), and identity propagation (carrying that context across service hops). Every public endpoint is protected; every internal call carries the callerβs token forward.
IUserService.UserId is available anywhere in the request scope. No threading the user ID through method signatures.Result with a stable code, not an exception β clients see the same shape as any other failure.| Module | Purpose |
|---|---|
| Authorization Abstractions | ITokenService, IUserService β the contracts your code depends on. |
| Authorization Identity | JWT bearer setup, UserStatusMiddleware, token generation, options. |
Client ββ[Authorization: Bearer eyJβ¦]βββΊ Service
β
βΌ
JwtBearer middleware (signature, expiry, audience)
β
βΌ
UserStatusMiddleware (blocked/deleted/disabled?)
β
βΌ
IUserService (scoped β UserId available)
β
βΌ
Endpoint / Command Pipeline
Internal calls forward the same bearer via BearerTokenHandler (see Networking) β the downstream service sees the same UserId.
"Jwt": {
"SigningKey": "<base64 256-bit key>",
"Issuer": "task-hub",
"Audience": "task-hub-users",
"ValidateSigningKey": true,
"ValidateAudience": true,
"ValidateIssuer": true,
"ValidateLifetime": true,
"ClockSkew": 300000
}
The FullHostBuilder calls AddAppIdentity() automatically when this section is present.
Authorization headers β keep it that way.RequireAuthorization() proves who, but a job-edit endpoint also needs to prove they own this job β typically as a pre-behavior in the Command Pipeline.SigningKey out of source. Inject via environment variable or secret manager.ClockSkew. Generous clock skew (e.g. 5 minutes) prevents clock-drift failures in microservice fleets, but extends the window of validity for stolen tokens.UserStatusMiddleware internals.BearerTokenHandler for forwarding tokens between services.Result codes.