0

解码在另一个应用程序中生成的令牌后,我需要检查是否过期。我在 Web 应用程序中使用了 OnActionExecuting,但在最小的 api 中没有使用此方法。

现在我通过检查响应来捕捉它,但我需要一个比这更好的解决方案。

程序.cs

builder.Services.AddSingleton(autoMapper);
builder.Services.AddAuthorization();
builder.Services.AddAuthentication("BearerAuthentication").AddScheme<Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions, BearerAuthendicationHandler>("BearerAuthentication", null);
var app = builder.Build();
app.UseAuthorization();
app.UseAuthentication();

app.MapGet("/countries", async (HttpContext http, CountryService service) =>
 {
     if (http.Response.StatusCode == 401) return Results.Unauthorized();    
      var result = service.GetAll(http.Request.Headers["lang"]);
     return Results.Ok(result);
 });

BearerAuthendicationHandler.cs

public class BearerAuthendicationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    public BearerAuthendicationHandler(
        Microsoft.Extensions.Options.IOptionsMonitor<AuthenticationSchemeOptions> options,
        ILoggerFactory logger,
        System.Text.Encodings.Web.UrlEncoder encoder,
        ISystemClock clock
        ) : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var authHeader = Request.Headers["Authorization"].ToString();
        try
        {
            if (authHeader != null && authHeader.StartsWith("bearer", StringComparison.OrdinalIgnoreCase))
            {
                var token = authHeader.Substring("Bearer ".Length).Trim();
                string secret = "secret_key";
                var key = Encoding.ASCII.GetBytes(secret);
                var handler = new JwtSecurityTokenHandler();
                var validations = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
                var claims = handler.ValidateToken(token, validations, out var tokenSecure);
                var exp = claims.Claims.FirstOrDefault(s => s.Type == "exp").Value;
                var timeStamp = long.Parse(exp);
                var timeStampNow = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
                if (timeStamp < timeStampNow)
                {
                    Response.StatusCode = 401;
                    return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header"));
                }

                Response.StatusCode = 200;
                return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(), null, "")));
            }
            else
            {
                Response.StatusCode = 401;
                return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header"));
            }
        }
        catch (Exception ex)
        {
            Response.StatusCode = 401;
            return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header"));
        }
    }
}

谢谢你的帮助。

4

0 回答 0