修复 token无法校验问题
This commit is contained in:
parent
7075ec039d
commit
658b75e3ad
|
|
@ -17,7 +17,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
this.baseService = baseService;
|
this.baseService = baseService;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 后台管理员登录
|
/// 管理员登录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="model"></param>
|
/// <param name="model"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
|
@ -36,7 +36,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
Oh.Error("登录失败,用户不存在!");
|
Oh.Error("登录失败,用户不存在!");
|
||||||
if (!admin!.Enable)
|
if (!admin!.Enable)
|
||||||
Oh.Error("登录失败,用户已锁定!");
|
Oh.Error("登录失败,用户已锁定!");
|
||||||
if (admin.Password != model.Password)
|
if (admin.Password != model.Password.GetMD5())
|
||||||
Oh.Error("登录失败,密码错误");
|
Oh.Error("登录失败,密码错误");
|
||||||
// 获取租户信息
|
// 获取租户信息
|
||||||
|
|
||||||
|
|
@ -48,5 +48,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
new Claim(ClaimEnum.Name, admin.Name),
|
new Claim(ClaimEnum.Name, admin.Name),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
using Learn.Archives.Core.Model;
|
||||||
|
|
||||||
|
namespace Learn.Archives.API.Controllers.Dto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 菜单树
|
||||||
|
/// </summary>
|
||||||
|
public class MenuTree : Menu
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 子菜单列表
|
||||||
|
/// </summary>
|
||||||
|
public MenuTree[] Children { get; set; } = Array.Empty<MenuTree>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
using Learn.Archives.API.Controllers.Dto;
|
||||||
|
using Learn.Archives.API.Expand;
|
||||||
|
using Learn.Archives.Core.Common;
|
||||||
|
using Learn.Archives.Core.Model;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using UserCenter.Model;
|
||||||
|
|
||||||
|
namespace Learn.Archives.API.Controllers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 路由菜单
|
||||||
|
/// </summary>
|
||||||
|
public class MenuController : BackController<Menu>
|
||||||
|
{
|
||||||
|
readonly Repository<Menu> baseService;
|
||||||
|
readonly Repository<MenuRelation> menuRelationDB;
|
||||||
|
readonly LiveUserInfo userInfo;
|
||||||
|
public MenuController(Repository<Menu> baseService, LiveUserInfo userInfo, Repository<MenuRelation> menuRelationDB) : base(baseService)
|
||||||
|
{
|
||||||
|
this.baseService = baseService;
|
||||||
|
this.userInfo = userInfo;
|
||||||
|
this.menuRelationDB = menuRelationDB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 管理员菜单
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<MenuTree[]> AdminMenu()
|
||||||
|
{
|
||||||
|
var rId = userInfo.RoleId;
|
||||||
|
if (rId == 0) Oh.Error("登录了无效的用户");
|
||||||
|
var menuArr = await menuRelationDB.AsQueryable()
|
||||||
|
.LeftJoin<Menu>((mr, m) => mr.MenuId == m.Id)
|
||||||
|
.Where((mr,m)=> mr.RoleId == userInfo.RoleId)
|
||||||
|
.Select((mr, m) => m)
|
||||||
|
.ToArrayAsync();
|
||||||
|
return GetChildren(menuArr, menuArr.First().Id);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 递归获取子菜单
|
||||||
|
/// </summary>
|
||||||
|
[NonAction]
|
||||||
|
private static MenuTree[] GetChildren(IEnumerable<Menu> menus, long parentId)
|
||||||
|
{
|
||||||
|
return menus
|
||||||
|
.Where(m => m.ParentId == parentId)
|
||||||
|
.OrderBy(m => m.Rank)
|
||||||
|
.Select(m => new MenuTree
|
||||||
|
{
|
||||||
|
Id = m.Id,
|
||||||
|
Name = m.Name,
|
||||||
|
Title = m.Title,
|
||||||
|
Path = m.Path,
|
||||||
|
IsButton = m.IsButton,
|
||||||
|
Icon = m.Icon,
|
||||||
|
Auths = m.Auths,
|
||||||
|
Rank = m.Rank,
|
||||||
|
ShowLink = m.ShowLink,
|
||||||
|
ParentId = m.ParentId,
|
||||||
|
Children = GetChildren(menus, m.Id)
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ using UserCenter.Model.Interface;
|
||||||
namespace Learn.Archives.API.Controllers
|
namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class BaseController : ControllerBase
|
public class _BaseController : ControllerBase
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Authorize(AuthenticationSchemes = Authentication.Admin)]
|
[Authorize(AuthenticationSchemes = Authentication.Admin)]
|
||||||
[Route("api/[controller]/[action]")]
|
[Route("api/[controller]/[action]")]
|
||||||
public abstract class BackBaseController : BaseController
|
public abstract class BackBaseController : _BaseController
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,9 +108,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public virtual ISugarQueryable<T> BaseQuery(QueryDto model)
|
public virtual ISugarQueryable<T> BaseQuery(QueryDto model)
|
||||||
{
|
{
|
||||||
List<IConditionalModel> where = new List<IConditionalModel>();
|
List<IConditionalModel> where = [.. model.Conditions];
|
||||||
foreach (var item in model.Conditions)
|
|
||||||
where.Add(item);
|
|
||||||
var d = _baseRepository.AsQueryable()
|
var d = _baseRepository.AsQueryable()
|
||||||
.Where(where);
|
.Where(where);
|
||||||
if ((typeof(T)).GetProperty("DeleteState") != null)
|
if ((typeof(T)).GetProperty("DeleteState") != null)
|
||||||
|
|
@ -143,11 +141,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(model.ValueName) || string.IsNullOrEmpty(model.TextName))
|
if (string.IsNullOrEmpty(model.ValueName) || string.IsNullOrEmpty(model.TextName))
|
||||||
Oh.ModelError("ValueName TextName 是必填项");
|
Oh.ModelError("ValueName TextName 是必填项");
|
||||||
List<IConditionalModel> where = [.. model.Conditions];
|
var sqlquery = BaseQuery(model);
|
||||||
var sqlquery = _baseRepository.AsQueryable().Where(where).Where("DeleteState=0");
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(model.OrderBy))
|
|
||||||
sqlquery = sqlquery.OrderByPropertyName(model.OrderBy, model.OrderByType);
|
|
||||||
var res = await sqlquery.Select<ComboModel>($"{model.TextName} as Text , {model.ValueName} as Value").ToListAsync();
|
var res = await sqlquery.Select<ComboModel>($"{model.TextName} as Text , {model.ValueName} as Value").ToListAsync();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Text;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Learn.Archives.Core.Model.Dto;
|
using Learn.Archives.Core.Model.Dto;
|
||||||
using Aliyun.OSS;
|
using Aliyun.OSS;
|
||||||
|
using NetTaste;
|
||||||
|
|
||||||
namespace Learn.Archives.API.Expand
|
namespace Learn.Archives.API.Expand
|
||||||
{
|
{
|
||||||
|
|
@ -18,6 +19,7 @@ namespace Learn.Archives.API.Expand
|
||||||
.AddJwtBearer(Authentication.Admin, options =>
|
.AddJwtBearer(Authentication.Admin, options =>
|
||||||
{
|
{
|
||||||
options.RequireHttpsMetadata = false;
|
options.RequireHttpsMetadata = false;
|
||||||
|
options.UseSecurityTokenValidators = true;
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
options.TokenValidationParameters = new TokenValidationParameters
|
||||||
{
|
{
|
||||||
SaveSigninToken = false,//保存token,后台验证token是否生效(重要)
|
SaveSigninToken = false,//保存token,后台验证token是否生效(重要)
|
||||||
|
|
@ -30,6 +32,19 @@ namespace Learn.Archives.API.Expand
|
||||||
};
|
};
|
||||||
options.Events = new JwtBearerEvents
|
options.Events = new JwtBearerEvents
|
||||||
{
|
{
|
||||||
|
OnMessageReceived = context =>
|
||||||
|
{
|
||||||
|
var token = context.Request.Headers["Authorization"].FirstOrDefault();
|
||||||
|
// 3. 安全提取令牌
|
||||||
|
if (!string.IsNullOrEmpty(token) && token.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// 移除"Bearer "前缀并清除两端空格
|
||||||
|
token = token.Substring("Bearer ".Length).Trim();
|
||||||
|
context.Token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
},
|
||||||
OnAuthenticationFailed = context =>
|
OnAuthenticationFailed = context =>
|
||||||
{
|
{
|
||||||
context.Response.Clear();
|
context.Response.Clear();
|
||||||
|
|
@ -41,11 +56,13 @@ namespace Learn.Archives.API.Expand
|
||||||
},
|
},
|
||||||
OnChallenge = context =>
|
OnChallenge = context =>
|
||||||
{
|
{
|
||||||
|
if(context.Response.StatusCode == 403 || context.Response.StatusCode == 401)
|
||||||
|
return Task.CompletedTask;
|
||||||
context.HandleResponse();
|
context.HandleResponse();
|
||||||
context.Response.Clear();
|
context.Response.Clear();
|
||||||
context.Response.ContentType = "application/json";
|
context.Response.ContentType = "application/json";
|
||||||
context.Response.StatusCode = 403;
|
context.Response.StatusCode = 401;
|
||||||
var data = new BaseReturn() { Code = 403, Message = context.Error + context.AuthenticateFailure?.Message };
|
var data = new BaseReturn() { Code = 401, Message = context.Error + context.AuthenticateFailure?.Message };
|
||||||
context.Response.WriteAsync(data.ToJson());
|
context.Response.WriteAsync(data.ToJson());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.18" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.18" />
|
||||||
|
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.13.0" />
|
||||||
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.13.0" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" />
|
||||||
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.2-pre01" />
|
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.2-pre01" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,18 +28,7 @@ builder.Services.AddControllers(options =>
|
||||||
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰
|
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰
|
||||||
});
|
});
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerExpand("学校档案系统");
|
||||||
{
|
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo
|
|
||||||
{
|
|
||||||
Version = "v1",
|
|
||||||
Description = "学校档案系统v1"
|
|
||||||
});
|
|
||||||
var file = Path.Combine(AppContext.BaseDirectory, "Learn.Archives.API.xml"); // xml文档绝对路径
|
|
||||||
c.IncludeXmlComments(file, true); // true : 显示控制器层注释
|
|
||||||
c.OrderActionsBy(o => o.RelativePath); // 对action的名称进行排序,如果有多个,就可以看见效果了。
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.Configuration.AddAppConfig(args);
|
builder.Configuration.AddAppConfig(args);
|
||||||
builder.Services.AddPermissionAuthentication();
|
builder.Services.AddPermissionAuthentication();
|
||||||
builder.Services.AddSqlSugarExpand();
|
builder.Services.AddSqlSugarExpand();
|
||||||
|
|
@ -54,12 +43,16 @@ builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
AppCommon.Services = app.Services;
|
||||||
|
|
||||||
app.UseMiddleware<BasicAuthMiddleware>("Swagger");
|
app.UseMiddleware<BasicAuthMiddleware>("Swagger");
|
||||||
|
|
||||||
|
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI();
|
app.UseSwaggerUI();
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
//自定义 应用
|
//自定义 应用
|
||||||
app.UseCorsExpand();
|
app.UseCorsExpand();
|
||||||
app.UseSqlSugarExpand();
|
app.UseSqlSugarExpand();
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.PortableExecutable;
|
using System.Reflection.PortableExecutable;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
@ -70,12 +71,16 @@ namespace Learn.Archives.Core.Common
|
||||||
public static class ExpandFunction
|
public static class ExpandFunction
|
||||||
{
|
{
|
||||||
|
|
||||||
static Dictionary<string, string> FormulaData;
|
|
||||||
static string FormulaDataKey;
|
|
||||||
/// <summary>
|
public static string GetMD5(this string input)
|
||||||
/// 帧文件名称
|
{
|
||||||
/// </summary>
|
using (MD5 md5 = MD5.Create())
|
||||||
public static string FrameName = "frame_";
|
{
|
||||||
|
byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
|
||||||
|
return Convert.ToHexString(hashBytes).ToUpper(); // 或者保留大写
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 对象转化为JSON字符串
|
/// 对象转化为JSON字符串
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
using Microsoft.AspNetCore.Http;
|
using Learn.Archives.Core.Model;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using OracleInternal.Secure.Network;
|
using OracleInternal.Secure.Network;
|
||||||
|
using SqlSugar.IOC;
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -12,6 +14,8 @@ namespace Learn.Archives.Core.Common
|
||||||
private readonly RequestDelegate _next;
|
private readonly RequestDelegate _next;
|
||||||
private readonly string _realm;
|
private readonly string _realm;
|
||||||
|
|
||||||
|
private Repository<Admin> baseservice;
|
||||||
|
|
||||||
public BasicAuthMiddleware(RequestDelegate next, string realm)
|
public BasicAuthMiddleware(RequestDelegate next, string realm)
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
|
|
@ -20,7 +24,8 @@ namespace Learn.Archives.Core.Common
|
||||||
|
|
||||||
public async Task InvokeAsync(HttpContext context)
|
public async Task InvokeAsync(HttpContext context)
|
||||||
{
|
{
|
||||||
if (context.Request.Path.StartsWithSegments("/swagger"))
|
if (context.Request.Path.StartsWithSegments("/swagger")
|
||||||
|
&& (context.Request.Path.Value?.Contains("swagger.json") ?? true))
|
||||||
{
|
{
|
||||||
string authHeader = context.Request.Headers["Authorization"];
|
string authHeader = context.Request.Headers["Authorization"];
|
||||||
if (authHeader != null && authHeader.StartsWith("Basic "))
|
if (authHeader != null && authHeader.StartsWith("Basic "))
|
||||||
|
|
@ -31,6 +36,7 @@ namespace Learn.Archives.Core.Common
|
||||||
|
|
||||||
if (await IsAuthorized(usernamePassword[0], usernamePassword[1]))
|
if (await IsAuthorized(usernamePassword[0], usernamePassword[1]))
|
||||||
{
|
{
|
||||||
|
|
||||||
await _next(context);
|
await _next(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -45,9 +51,19 @@ namespace Learn.Archives.Core.Common
|
||||||
|
|
||||||
private async Task<bool> IsAuthorized(string username, string password)
|
private async Task<bool> IsAuthorized(string username, string password)
|
||||||
{
|
{
|
||||||
// 在这里验证用户名和密码
|
//if (baseservice == null)
|
||||||
return AppCommon.Config.Admin.Account == username
|
//{
|
||||||
&& AppCommon.Config.Admin.Password == password;
|
// using var scope = AppCommon.Services?.CreateScope();
|
||||||
|
// if (scope != null)
|
||||||
|
// baseservice = scope.ServiceProvider.GetService<Repository<Admin>>();
|
||||||
|
//}
|
||||||
|
//if (baseservice == null) return false;
|
||||||
|
|
||||||
|
var admin = await DbScoped.Sugar.Queryable<Admin>()
|
||||||
|
.FirstAsync(x => x.Account == username);
|
||||||
|
if (admin == null || !admin!.Enable) return false;
|
||||||
|
else if (admin.Password != password.GetMD5()) return false;
|
||||||
|
else return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Learn.Archives.Core.Common.Expand
|
||||||
|
{
|
||||||
|
public static class SwaggerExpand
|
||||||
|
{
|
||||||
|
public static void AddSwaggerExpand(this IServiceCollection s,string name="")
|
||||||
|
{
|
||||||
|
s.AddSwaggerGen(c =>
|
||||||
|
{
|
||||||
|
c.SwaggerDoc("v1", new OpenApiInfo
|
||||||
|
{
|
||||||
|
Version = "v1",
|
||||||
|
Description = name
|
||||||
|
});
|
||||||
|
c.OperationFilter<SwaggerFileUploadFilter>();
|
||||||
|
//按Http类型排序
|
||||||
|
c.OrderActionsBy(o => o.GroupName);
|
||||||
|
|
||||||
|
c.DocInclusionPredicate((docName, apiDesc) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!apiDesc.TryGetMethodInfo(out MethodInfo methodInfo)) return false;
|
||||||
|
var versions = methodInfo.DeclaringType.GetCustomAttributes(true)
|
||||||
|
.OfType<ApiExplorerSettingsAttribute>().Select(attr => attr.GroupName);
|
||||||
|
if (docName.ToLower() == "v1" && versions.FirstOrDefault() == null)
|
||||||
|
return true;
|
||||||
|
return versions.Any(v => v.ToString() == docName);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//添加全局安全性需求
|
||||||
|
c.AddSecurityRequirement(new OpenApiSecurityRequirement{
|
||||||
|
{
|
||||||
|
new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new OpenApiReference
|
||||||
|
{
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
Id = "bearerAuth"
|
||||||
|
}
|
||||||
|
}, Array.Empty<string>()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。
|
||||||
|
c.AddSecurityDefinition("bearerAuth",
|
||||||
|
new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Description = "使用JWT授权头。示例:\"Authorization: Bearer {token}\"",
|
||||||
|
Name = "Authorization",
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Type = SecuritySchemeType.Http,
|
||||||
|
//内容为以 bearer开头
|
||||||
|
Scheme = "bearer",
|
||||||
|
BearerFormat = "JWT"
|
||||||
|
});
|
||||||
|
|
||||||
|
DirectoryInfo dirs = new DirectoryInfo(AppContext.BaseDirectory);
|
||||||
|
FileInfo[] files = dirs.GetFiles("*.xml");
|
||||||
|
foreach (var path in files)
|
||||||
|
{
|
||||||
|
c.IncludeXmlComments(path.FullName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//s.AddSwaggerGenNewtonsoftSupport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SwaggerFileUploadFilter : IOperationFilter
|
||||||
|
{
|
||||||
|
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||||
|
{
|
||||||
|
if (context.ApiDescription.ActionDescriptor.Parameters.Any(w => w.ParameterType == typeof(IFormCollection)))
|
||||||
|
{
|
||||||
|
Dictionary<string, OpenApiSchema> schema = new Dictionary<string, OpenApiSchema>();
|
||||||
|
schema["fileName"] = new OpenApiSchema { Description = "选择上传文件", Type = "string", Format = "binary" };
|
||||||
|
Dictionary<string, OpenApiMediaType> content = new Dictionary<string, OpenApiMediaType>();
|
||||||
|
content["multipart/form-data"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "object", Properties = schema } };
|
||||||
|
operation.RequestBody = new OpenApiRequestBody() { Content = content };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Learn.Archives.Core.Common
|
||||||
//JWT ID 唯一标识符
|
//JWT ID 唯一标识符
|
||||||
new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString() ),
|
new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString() ),
|
||||||
//发布时间戳 issued timestamp
|
//发布时间戳 issued timestamp
|
||||||
new Claim(JwtRegisteredClaimNames.Iat, now.ToString()),
|
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64),
|
||||||
};
|
};
|
||||||
if (claims != null && claims.Length > 0)
|
if (claims != null && claims.Length > 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,9 @@ namespace Learn.Archives.Core.Common
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 管理员角色id
|
/// 管理员角色id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? RoleId
|
public long? RoleId
|
||||||
{
|
{
|
||||||
get => _httpContextAccessor.HttpContext?.User.FindFirst(ClaimEnum.Role)?.Value;
|
get => long.Parse(_httpContextAccessor.HttpContext?.User.FindFirst(ClaimEnum.Role)?.Value ?? "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ using System.Threading.Channels;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using UserCenter.Model.Enum;
|
using UserCenter.Model.Enum;
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
||||||
|
|
||||||
namespace Learn.Archives.Core.Common
|
namespace Learn.Archives.Core.Common
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
||||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.170" />
|
<PackageReference Include="SqlSugarCore" Version="5.1.4.170" />
|
||||||
<PackageReference Include="UserCenter.Model" Version="1.3.9" />
|
<PackageReference Include="UserCenter.Model" Version="1.3.9" />
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Learn.Archives.Core.Model
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 密码
|
/// 密码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(Length = 12)]
|
[SugarColumn(Length = 32)]
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 启用
|
/// 启用
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,16 @@ namespace Learn.Archives.Core.Model
|
||||||
/// 名称
|
/// 名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(Length = 50)]
|
[SugarColumn(Length = 50)]
|
||||||
public required string Name { get; set; }
|
public string Name { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标题
|
/// 标题
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(Length = 20)]
|
[SugarColumn(Length = 20)]
|
||||||
public required string Title { get; set; }
|
public string Title { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 路径
|
/// 路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
public string? Path { get; set; }
|
public string? Path { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是按钮权限
|
/// 是按钮权限
|
||||||
|
|
@ -36,10 +37,12 @@ namespace Learn.Archives.Core.Model
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 图标
|
/// 图标
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
public string? Icon { get; set; }
|
public string? Icon { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 需要的授权码
|
/// 需要的授权码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
public string? Auths { get; set; }
|
public string? Auths { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 排名
|
/// 排名
|
||||||
|
|
@ -51,5 +54,12 @@ namespace Learn.Archives.Core.Model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowLink { get; set; }
|
public bool ShowLink { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 父级菜单ID
|
||||||
|
/// <para>属于<see cref="Menu.Id"/></para>
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public long ParentId { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ namespace Learn.Archives.Core.Model
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 菜单id
|
/// 菜单id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required long MenuId { get; set; }
|
public long MenuId { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 管理员id
|
/// 角色id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required long AdminId { get; set; }
|
public long RoleId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建时间
|
/// 创建时间
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue