如何通过授权过滤器实现黑名单令牌校验并返回未授权状态码
完善访问令牌黑名单检查的授权过滤器
Hey there, let's fix and polish your token blacklist authorization filter to make it robust and production-ready. Your current code has a few key gaps we need to address:
- You're using a hardcoded token value instead of extracting the actual access token from the incoming request
- The async method isn't properly handling asynchronous operations or early termination when a banned token is found
- The placeholder
TokenInBlackListmethod needs a real implementation that integrates with your blacklist storage (like Redis or a database)
Here's the improved implementation with explanations:
Complete Working Code
public class CheckBannedTokenAttribute : Attribute, IAsyncAuthorizationFilter { private readonly ITokenBlackListService _tokenBlackListService; // Inject the blacklist service via constructor for better testability and separation of concerns public CheckBannedTokenAttribute(ITokenBlackListService tokenBlackListService) { _tokenBlackListService = tokenBlackListService; } public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { // Step 1: Extract the Bearer token from the Authorization header var authHeader = context.HttpContext.Request.Headers["Authorization"].FirstOrDefault(); if (string.IsNullOrWhiteSpace(authHeader) || !authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { // No valid token provided - return unauthorized context.Result = new UnauthorizedResult(); return; } var accessToken = authHeader.Substring("Bearer ".Length).Trim(); // Step 2: Check if the token exists in the blacklist var isTokenBanned = await _tokenBlackListService.IsTokenInBlackListAsync(accessToken); if (isTokenBanned) { // Token is banned - block the request context.Result = new UnauthorizedResult(); return; } // Step 3: Token is valid and not banned - proceed with normal authorization flow } } // Interface for the blacklist service (follows dependency inversion principle) public interface ITokenBlackListService { Task<bool> IsTokenInBlackListAsync(string token); } // Example implementation using Redis (replace with your actual storage logic) public class TokenBlackListService : ITokenBlackListService { private readonly IDistributedCache _distributedCache; public TokenBlackListService(IDistributedCache distributedCache) { _distributedCache = distributedCache; } public async Task<bool> IsTokenInBlackListAsync(string token) { // We store banned tokens in Redis with a key like "banned-token:{token}" var cacheKey = $"banned-token:{token}"; var bannedTokenRecord = await _distributedCache.GetStringAsync(cacheKey); // If the record exists, the token is banned return !string.IsNullOrEmpty(bannedTokenRecord); } }
Key Improvements Explained
- Dependency Injection: By injecting
ITokenBlackListService, we decouple the filter from the actual blacklist storage logic, making it easier to test and swap out storage providers later. - Proper Token Extraction: We follow the standard Bearer token pattern to pull the access token from the request headers, which is how most JWT-based auth systems work.
- Async-Await Support: All operations that touch external storage (like Redis) use async methods to avoid blocking the request thread, improving application scalability.
- Early Flow Termination: As soon as we detect an invalid or banned token, we set
context.Resultand return immediately, ensuring no unnecessary subsequent authorization logic runs. - Separation of Concerns: The blacklist check logic lives in a dedicated service, keeping the authorization filter focused on its core job.
Additional Setup Notes
Don't forget to register your service in your application's dependency injection container (in Program.cs or Startup.cs):
// Register the blacklist service and its implementation builder.Services.AddScoped<ITokenBlackListService, TokenBlackListService>(); // If using Redis, make sure to register the distributed cache too builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = "your-redis-connection-string"; });
Optional Enhancements
- Add logging to track banned token attempts (use
ILoggerinjected into the filter) - Validate token signature/expiry before checking the blacklist (to avoid wasting resources on invalid tokens)
- Adjust token extraction logic if your app uses a different method (e.g., query parameters, cookies)
内容的提问来源于stack exchange,提问作者Jhon Duck
相关产品推荐
相关产品推荐

