feat(auth): 添加统一 API 和 PC 认证端点
- 新增 API 端 JWT 登录、refresh token 轮换和退出登录流程 - 新增 refresh token 实体、DbSet 配置和 EF Core 迁移 - 新增 PC 端授权码登录、本地全局 token 刷新、登出和鉴权服务 - 扩展统一端点模型,支持宿主过滤、角色鉴权、OpenAPI 元数据和 DI 服务处理器 - API 启用 JwtBearer 认证、Swagger UI 和认证端点注册 - PC 端注册认证服务,并按宿主过滤桌面拦截端点
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Avalonia_Services.Core;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using AspNetCoreFilterContext = Microsoft.AspNetCore.Http.EndpointFilterInvocationContext;
|
||||
using AspNetCoreFilterDelegate = Microsoft.AspNetCore.Http.EndpointFilterDelegate;
|
||||
// 解决与 ASP.NET Core 同名类型的冲突
|
||||
@@ -22,7 +23,7 @@ namespace Avalonia_API.Extensions
|
||||
{
|
||||
var apiGroup = routeBuilder.MapGroup("/");
|
||||
|
||||
foreach (var endpoint in endpoints.Endpoints)
|
||||
foreach (var endpoint in endpoints.ForHost(EndpointHostTarget.Api))
|
||||
{
|
||||
var routeHandlerBuilder = MapEndpoint(apiGroup, endpoint, serviceProvider);
|
||||
|
||||
@@ -43,7 +44,14 @@ namespace Avalonia_API.Extensions
|
||||
// 鉴权(使用 ASP.NET Core 原生鉴权机制)
|
||||
if (endpoint.RequireAuthorization)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(endpoint.Policy))
|
||||
if (endpoint.Roles.Count > 0)
|
||||
{
|
||||
routeHandlerBuilder.RequireAuthorization(new AuthorizeAttribute
|
||||
{
|
||||
Roles = string.Join(',', endpoint.Roles),
|
||||
});
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(endpoint.Policy))
|
||||
{
|
||||
routeHandlerBuilder.RequireAuthorization(endpoint.Policy);
|
||||
}
|
||||
@@ -57,6 +65,31 @@ namespace Avalonia_API.Extensions
|
||||
{
|
||||
routeHandlerBuilder.WithName(endpoint.Name);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(endpoint.OpenApiTag))
|
||||
{
|
||||
routeHandlerBuilder.WithTags(endpoint.OpenApiTag);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(endpoint.OpenApiDescription))
|
||||
{
|
||||
routeHandlerBuilder.WithDescription(endpoint.OpenApiDescription);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(endpoint.OpenApiSummary))
|
||||
{
|
||||
routeHandlerBuilder.WithSummary(endpoint.OpenApiSummary);
|
||||
}
|
||||
|
||||
if (endpoint.OpenApiRequestType is not null)
|
||||
{
|
||||
routeHandlerBuilder.Accepts(endpoint.OpenApiRequestType, "application/json");
|
||||
}
|
||||
|
||||
if (endpoint.OpenApiResponseType is not null)
|
||||
{
|
||||
routeHandlerBuilder.Produces(200, endpoint.OpenApiResponseType, "application/json");
|
||||
}
|
||||
}
|
||||
|
||||
return routeBuilder;
|
||||
@@ -87,6 +120,7 @@ namespace Avalonia_API.Extensions
|
||||
{
|
||||
var ctx = await BuildContextFromHttpContext(httpContext);
|
||||
ctx.Items["ServiceProvider"] = serviceProvider;
|
||||
ctx.Items["User"] = httpContext.User;
|
||||
|
||||
var result = await unifiedHandler(ctx);
|
||||
|
||||
@@ -127,6 +161,7 @@ namespace Avalonia_API.Extensions
|
||||
}
|
||||
|
||||
ctx.Items["HttpContext"] = httpContext;
|
||||
ctx.Items["User"] = httpContext.User;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user