You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET中为除登录注册外的接口前置JWT验证?

How to Implement JWT Validation via Action Filter for All Except LogIn/Register Endpoints

Got it, let's solve this problem step by step. You absolutely can implement JWT validation using an Action Filter—you just need to access the request headers correctly from the filter context. Here's how to adapt your existing validation logic into a reusable filter, and apply it across your controllers while excluding the LogIn/Register endpoints.

1. Create a Custom JWT Authorization Action Filter

First, we'll build a custom ActionFilterAttribute that handles token extraction, validation, and returns an unauthorized response if validation fails. We'll integrate your existing validation logic here, and add checks to skip validation for endpoints that shouldn't require it (like LogIn/Register).

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

public class JwtAuthorizeAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Skip validation if the action has [AllowAnonymous] attribute
        if (context.ActionDescriptor.EndpointMetadata.Any(em => em is AllowAnonymousAttribute))
        {
            base.OnActionExecuting(context);
            return;
        }

        // Extract token from Authorization header
        if (!context.HttpContext.Request.Headers.TryGetValue("Authorization", out var tokenHeader))
        {
            context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedResult();
            return;
        }

        string token = tokenHeader.ToString();
        if (!token.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
        {
            context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedResult();
            return;
        }

        string sToken = token.Substring(7);
        bool isValid = ValidateToken(sToken);

        if (!isValid)
        {
            context.Result = new Microsoft.AspNetCore.Mvc.UnauthorizedResult();
            return;
        }

        // If validation passes, proceed with the action
        base.OnActionExecuting(context);
    }

    private bool ValidateToken(string token)
    {
        try
        {
            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            
            if (!tokenHandler.CanReadToken(token))
            {
                return false;
            }

            JwtSecurityToken jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;
            if (jwtToken == null)
            {
                return false;
            }

            TokenValidationParameters parameters = new TokenValidationParameters()
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                RequireExpirationTime = true,
                ValidAudience = "http://localhost",
                ValidIssuer = "http://localhost",
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(StandardValues.SecretKey))
            };

            SecurityToken securityToken;
            ClaimsPrincipal principal = tokenHandler.ValidateToken(token, parameters, out securityToken);
            
            return principal != null;
        }
        catch (Exception)
        {
            return false;
        }
    }
}

2. Apply the Filter to Your Controllers

You have a few flexible options to apply this filter based on your needs:

Option 1: Global Application (Applies to All Endpoints by Default)

If you want validation to apply to every endpoint automatically (and only exclude LogIn/Register), register the filter globally in your Program.cs:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers(options =>
{
    options.Filters.Add<JwtAuthorizeAttribute>();
});

// ... rest of your service configuration

var app = builder.Build();

// ... middleware configuration

app.MapControllers();

app.Run();

Then, add the [AllowAnonymous] attribute to your LogIn and Register actions to bypass validation:

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
    [HttpPost("login")]
    [AllowAnonymous]
    public IActionResult LogIn([FromBody] LoginModel model)
    {
        // Your login logic here
        return Ok();
    }

    [HttpPost("register")]
    [AllowAnonymous]
    public IActionResult Register([FromBody] RegisterModel model)
    {
        // Your registration logic here
        return Ok();
    }
}

Option 2: Controller-Level Application

If you only want to enforce validation on specific controllers, add the [JwtAuthorize] attribute directly to those controllers:

[ApiController]
[Route("api/users")]
[JwtAuthorize]
public class UsersController : ControllerBase
{
    // All actions in this controller will require JWT validation
    [HttpGet]
    public IActionResult GetUsers()
    {
        return Ok();
    }
}

You can still use [AllowAnonymous] on individual actions within these controllers if you need to exempt specific endpoints.

3. Key Notes

  • Token Format: Ensure your clients send the token in the Authorization header using the Bearer scheme (Bearer <your-token>)—the filter expects this format to extract the token correctly.
  • Immediate Failure Handling: If validation fails at any step, the filter returns a 401 Unauthorized response right away, stopping the target action from executing.
  • Reusability: This filter encapsulates all your JWT validation logic, so you don't have to duplicate code across multiple controllers or actions.

内容的提问来源于stack exchange,提问作者AndreiB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:14:14