.NET8发布后,AOT解决了JWT Authentication
随着.NET8发布,AOT的JWT Authentication也完成了,这样,构建一个基本的AOT API成为了可能,可以把AOT引入到一些简单的API项目中来了。关于AOT的好处,请参照:
https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/native-aot?view=aspnetcore-8.0。
下面是一增加JWT Authentication的一个简单Demo,时间仓促,仅供参考。
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security; using System.Security.Claims; using System.Text; using System.Text.Json.Serialization; var builder = WebApplication.CreateSlimBuilder(args); builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default); }); #region 策略 builder.Services .AddAuthorization(options => { //添加策略名称 options.AddPolicy("Permission", policyBuilder => policyBuilder.AddRequirements(new PermissionRequirement())); }) .AddSingleton(new List<Permission> { new Permission { RoleName = "admin", Url = "/Policy", Method = "get" }, new Permission { RoleName = "admin", Url = "/todos", Method = "get" }, }) .AddSingleton<IAuthorizationHandler, PermissionHandler>() .AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; } ).AddJwtBearer(opt => { //token验证参数 opt.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("1234567890abcdefg1234567890abcdefg")), ValidateIssuer = true, ValidIssuer = "http://localhost:5274", ValidateAudience = true, ValidAudience = "http://localhost:5274", ClockSkew = TimeSpan.Zero, RequireExpirationTime = true, }; }); #endregion var app = builder.Build(); var sampleTodos = new Todo[] { new(1, "Walk the dog"), new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)), new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))), new(4, "Clean the bathroom"), new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2))) }; var todosApi = app.MapGroup("/todos"); todosApi.MapGet("/", () => sampleTodos).RequireAuthorization("Permission"); ; todosApi.MapGet("/{id}", (int id) => sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo ? Results.Ok(todo) : Results.NotFound()).RequireAuthorization("Permission"); #region 策略 app.MapGet("/login", () => { //用JWTSecurityTokenHandler生成token return new JwtSecurityTokenHandler().WriteToken( new JwtSecurityToken( issuer: "http://localhost:5274", audience: "http://localhost:5274", claims: new Claim[] { new Claim(ClaimTypes.Role, "admin"), new Claim(ClaimTypes.Name, "桂素伟") }, notBefore: DateTime.UtcNow, expires: DateTime.UtcNow.AddSeconds(500000), signingCredentials: new SigningCredentials( new SymmetricSecurityKey(Encoding.ASCII.GetBytes("1234567890abcdefg1234567890abcdefg")), SecurityAlgorithms.HmacSha256Signature) ) ); }); app.MapGet("/policy", (ClaimsPrincipal user) => $"Hello 用户:{user.Identity?.Name}, 角色:{user.Claims?.Where(s => s.Type == ClaimTypes.Role).First().Value}. This is a policy!").RequireAuthorization("Permission"); #endregion app.Run(); public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false); [JsonSerializable(typeof(Todo[]))] internal partial class AppJsonSerializerContext : JsonSerializerContext { } #region 策略 public class PermissionRequirement : IAuthorizationRequirement { } public class Permission { public string? RoleName { get; set; } public string? Url { get; set; } public string? Method { get; set; } } public class PermissionHandler : AuthorizationHandler<PermissionRequirement> { private readonly List<Permission> _userPermissions; public PermissionHandler(List<Permission> permissions) { _userPermissions = permissions; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { if (context.Resource is DefaultHttpContext) { var httpContext = context.Resource as DefaultHttpContext; var questPath = httpContext?.Request?.Path; var method = httpContext?.Request?.Method; var isAuthenticated = context?.User?.Identity?.IsAuthenticated; if (isAuthenticated.HasValue && isAuthenticated.Value) { var role = context?.User?.Claims?.SingleOrDefault(s => s.Type == ClaimTypes.Role)?.Value; if (_userPermissions.Where(w => w.RoleName == role && w.Method?.ToUpper() == method?.ToUpper() && w.Url?.ToLower() == questPath).Count() > 0) { context?.Succeed(requirement); } else { context?.Fail(); } } } return Task.CompletedTask; } } #endregion
下面是演示结果:
登录:
查看登录信息:
查数据接口:
还有很多模板不支持或不完全支持AOT,下面是当前.NET8发布的适配情况。
Feature | Fully Supported | Partially Supported | Not Supported |
---|---|---|---|
gRPC | ✅Fully supported | ||
Minimal APIs | ✅Partially supported | ||
MVC | ❌Not supported | ||
Blazor | ❌Not supported | ||
SignalR | ❌Not supported | ||
JWT Authentication | ✅Fully supported | ||
Other Authentication | ❌Not supported | ||
CORS | ✅Fully supported | ||
Health checks | ✅Fully supported | ||
Http logging | ✅Fully supported | ||
Localization | ✅Fully supported | ||
Output caching | ✅Fully supported | ||
Rate limiting | ✅Fully supported | ||
Request decompression | ✅Fully supported | ||
Response caching | ✅Fully supported | ||
Response compression | ✅Fully supported | ||
Rewrite | ✅Fully supported | ||
Session | ❌Not supported | ||
SPA | ❌Not supported | ||
Static files | ✅Fully supported | ||
WebSockets | ✅Fully supported |
文章来源微信公众号
想要更快更方便的了解相关知识,可以关注微信公众号
****欢迎关注我的asp.net core系统课程****
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2008-02-18 .net知识和学习方法系列(七)string类型