diff --git a/FunGame.WebAPI/Architecture/CustomBearerTokenHandler.cs b/FunGame.WebAPI/Architecture/CustomBearerTokenHandler.cs new file mode 100644 index 0000000..6187537 --- /dev/null +++ b/FunGame.WebAPI/Architecture/CustomBearerTokenHandler.cs @@ -0,0 +1,44 @@ +using System.Security.Claims; +using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Options; +using Milimoe.FunGame.Core.Api.Utility; + +namespace Milimoe.FunGame.WebAPI.Architecture +{ + public class CustomBearerAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder) : AuthenticationHandler(options, logger, encoder) + { + protected override async Task HandleAuthenticateAsync() + { + // 检查是否有 Authorization Header + if (!Request.Headers.TryGetValue("Authorization", out Microsoft.Extensions.Primitives.StringValues value)) + { + return AuthenticateResult.Fail("Authorization header is missing."); + } + + string authorizationHeader = value.ToString(); + if (!authorizationHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) + { + return AuthenticateResult.Fail("Invalid Authorization header format."); + } + + string token = authorizationHeader["Bearer ".Length..].Trim(); + + // 验证自定义 Token + string name = WebAPIAuthenticator.ValidateToken(token); + if (name == "") + { + await Task.Delay(1); + return AuthenticateResult.Fail("Invalid Token."); + } + + // 如果验证通过,创建 ClaimsIdentity + Claim[] claims = [new Claim(ClaimTypes.Name, name)]; + ClaimsIdentity identity = new(claims, Scheme.Name); + ClaimsPrincipal principal = new(identity); + AuthenticationTicket ticket = new(principal, Scheme.Name); + + return AuthenticateResult.Success(ticket); + } + } +} diff --git a/FunGame.WebAPI/Program.cs b/FunGame.WebAPI/Program.cs index 33e253e..bec90f1 100644 --- a/FunGame.WebAPI/Program.cs +++ b/FunGame.WebAPI/Program.cs @@ -4,6 +4,7 @@ using System.Text; using System.Text.Encodings.Web; using System.Text.Json.Serialization; using System.Text.Unicode; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Mvc.ApplicationParts; @@ -147,7 +148,11 @@ try }); // JWT ֤ builder.Services.AddScoped(); - builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => + builder.Services.AddAuthentication(options => + { + options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { @@ -159,7 +164,7 @@ try ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"] ?? "undefined")) }; - }); + }).AddScheme("CustomBearer", options => { }); WebApplication app = builder.Build();