feat: 优化权限使用方式

This commit is contained in:
陈淳
2023-02-21 18:56:51 +08:00
parent f8445ab2e4
commit 24300e6e50
13 changed files with 214 additions and 26 deletions

View File

@@ -0,0 +1,3 @@
<Project>
</Project>

View File

@@ -0,0 +1,90 @@

using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyCompany("YiFramework")]
[assembly: AssemblyFileVersion(VersionInfo.FullVersion)]
[assembly: AssemblyInformationalVersion(VersionInfo.FullVersion)]
[assembly: AssemblyVersion(VersionInfo.FullVersion)]
[assembly: ComVisible(false)]
#pragma warning disable IDE1006 // 命名样式
internal static class VersionInfo
{
/// <summary>
/// 主版本: 项目进行了重大修改导致不再向下兼容主版本号加1其它版本号清0
/// </summary>
public const string Major = "1";
/// <summary>
/// 次版本项目进行了重构增加了功能但向下兼容子版本号加1主版本号不变 修正版本号清0
/// </summary>
public const string Minor = "1";
/// <summary>
/// 生成号
/// </summary>
public const string Build = "0";
/// <summary>
/// 修订号项目进行了Bug修复向下兼容修正版本号加1主版本号、子版本号不 变;
/// </summary>
public const string Revision = "0";
/// <summary>
/// 版本名称
/// </summary>
public const string VersionName = null;
/// <summary>
/// 版本
/// </summary>
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
#pragma warning disable CS1570 // XML 注释出现 XML 格式错误
/// <summary>
/// 比较 a,b两个版本
/// 当 a > b 时,返回 1
/// 当 a = b 时,返回 0
/// 当 a < b 时,返回 -1
/// </summary>
#pragma warning restore CS1570 // XML 注释出现 XML 格式错误
public static int Compare(this Version a, Version b)
{
// 比较主版本
if (a.Major != b.Major)
{
return a.Major > b.Major ? 1 : -1;
}
// 比较次版本
if (a.Minor != b.Minor)
{
return a.Minor > b.Minor ? 1 : -1;
}
// 比较生成号
if (a.Build < 0 || b.Build < 0)
{
return 0;
}
if (a.Build != b.Build)
{
return a.Build > b.Build ? 1 : -1;
}
// 比较修订号
if (a.Revision < 0 || b.Revision < 0)
{
return 0;
}
if (a.Revision != b.Revision)
{
return a.Revision > b.Revision ? 1 : -1;
}
return 0;
}
#pragma warning restore IDE1006 // 命名样式
}

View File

@@ -85,7 +85,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.RBAC.Web", "src\project\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ThumbnailSharp", "src\module\Yi.Framework.ThumbnailSharp\Yi.Framework.ThumbnailSharp.csproj", "{60E54034-792C-4A90-BCDF-4D5FFB45089E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.EventBus", "src\module\Yi.Framework.EventBus\Yi.Framework.EventBus.csproj", "{FC559052-36EC-4379-B447-298FAD6045F4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.EventBus", "src\module\Yi.Framework.EventBus\Yi.Framework.EventBus.csproj", "{FC559052-36EC-4379-B447-298FAD6045F4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{12EA3BCF-8991-4010-B41E-67C476CBA690}"
ProjectSection(SolutionItems) = preProject
Build.props = Build.props
..\readme\git提交规范.txt = ..\readme\git提交规范.txt
src\project\rbac\GlobalUsings.cs = src\project\rbac\GlobalUsings.cs
Version.cs = Version.cs
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@@ -17,30 +17,13 @@ namespace Yi.Framework.Auth.JwtBearer.Authorization
public class PermissionAttribute : ActionFilterAttribute
{
private string Permission { get; set; }
internal string Code { get; set; }
public PermissionAttribute(string permission)
public PermissionAttribute(string code)
{
this.Permission = permission;
this.Code = code;
}
/// <summary>
/// 动作鉴权
/// </summary>
/// <param name="context"></param>
/// <exception cref="Exception"></exception>
public override void OnActionExecuting(ActionExecutingContext context)
{
var permissionHandler = ServiceLocatorModel.Instance.GetRequiredService<IPermissionHandler>();
var result = permissionHandler.IsPass(Permission);
if (!result)
{
throw new AuthException(message: $"您无权限访问该接口-{ context.HttpContext.Request.Path.Value}");
}
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Yi.Framework.Auth.JwtBearer.Authorization;
using Yi.Framework.Core.Exceptions;
namespace SF.AspNetCore.Auth.Authorization;
public class PermissionGlobalAttribute : ActionFilterAttribute
{
private readonly IPermissionHandler _permissionHandler;
public PermissionGlobalAttribute(IPermissionHandler permissionHandler)
{
_permissionHandler=permissionHandler;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return;
PermissionAttribute? perAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
.FirstOrDefault(a => a.GetType().Equals(typeof(PermissionAttribute))) as PermissionAttribute;
//空对象直接返回
if (perAttribute is null) return;
var result = _permissionHandler.IsPass(perAttribute.Code);
if (!result)
{
throw new AuthException(message: $"您无权限访问该接口-{context.HttpContext.Request.Path.Value}");
}
}
}

View File

@@ -1,5 +1,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using SF.AspNetCore.Auth.Authorization;
using StartupModules;
using System;
using System.Collections.Generic;
@@ -32,6 +34,10 @@ namespace Yi.Framework.Auth.JwtBearer
{
option.AddScheme<YiJwtAuthenticationHandler>(YiJwtAuthenticationHandler.YiJwtSchemeName, YiJwtAuthenticationHandler.YiJwtSchemeName);
});
services.AddSingleton<PermissionGlobalAttribute>();
services.AddControllers(options => {
options.Filters.Add<PermissionGlobalAttribute>();
});
//services.AddSingleton<PermissionAttribute>();
//services.AddControllers(options => {
// options.Filters.Add<PermissionAttribute>();

View File

@@ -11,6 +11,7 @@ using Yi.RBAC.Domain.Identity.Repositories;
using SqlSugar;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Yi.Framework.Auth.JwtBearer.Authorization;
namespace Yi.RBAC.Application.Identity
{

View File

@@ -10,7 +10,5 @@ namespace Yi.RBAC.Domain.Shared.Identity.Etos
{
public long UserId { get; set; }
public string UserName { get; set; }
public string LogMsg { get; set; }
}
}

View File

@@ -741,6 +741,20 @@
登录信息
</summary>
</member>
<member name="M:Yi.RBAC.Domain.Logs.Event.LoginEventHandler.GetClientInfo(Microsoft.AspNetCore.Http.HttpContext)">
<summary>
获取客户端信息
</summary>
<param name="context"></param>
<returns></returns>
</member>
<member name="M:Yi.RBAC.Domain.Logs.Event.LoginEventHandler.GetLoginLogInfo(Microsoft.AspNetCore.Http.HttpContext)">
<summary>
记录用户登陆信息
</summary>
<param name="context"></param>
<returns></returns>
</member>
<member name="T:Yi.RBAC.Domain.Setting.Entities.ConfigEntity">
<summary>
配置表

View File

@@ -1,4 +1,5 @@
using Cike.EventBus.EventHandlerAbstracts;
using IPTools.Core;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
@@ -6,6 +7,8 @@ using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using UAParser;
using Yi.Framework.AspNetCore.Extensions;
using Yi.Framework.Ddd.Repositories;
using Yi.RBAC.Domain.Logs.Entities;
using Yi.RBAC.Domain.Shared.Identity.Etos;
@@ -23,14 +26,56 @@ namespace Yi.RBAC.Domain.Logs.Event
}
public Task HandlerAsync(LoginEventArgs eventData)
{
var loginLogEntity = new LoginLogEntity();
var loginLogEntity = GetLoginLogInfo(_httpContext);
loginLogEntity.Id = SnowflakeHelper.NextId;
loginLogEntity.LogMsg = eventData.LogMsg;
loginLogEntity.LogMsg = eventData.UserName + "登录系统";
loginLogEntity.LoginUser = eventData.UserName;
loginLogEntity.LoginIp = _httpContext.GetClientIp();
_loginLogRepository.InsertAsync(loginLogEntity);
Console.WriteLine(eventData.UserName + "登录系统");
return Task.CompletedTask;
}
/// <summary>
/// 获取客户端信息
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private static ClientInfo GetClientInfo(HttpContext context)
{
var str = context.GetUserAgent();
var uaParser = Parser.GetDefault();
ClientInfo c = uaParser.Parse(str);
return c;
}
/// <summary>
/// 记录用户登陆信息
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private static LoginLogEntity GetLoginLogInfo(HttpContext context)
{
var ipAddr = context.GetClientIp();
IpInfo location;
if (ipAddr == "127.0.0.1")
{
location = new IpInfo() { Province = "本地", City = "本机" };
}
else
{
location = IpTool.Search(ipAddr);
}
ClientInfo clientInfo = GetClientInfo(context);
LoginLogEntity entity = new()
{
Browser = clientInfo.Device.Family,
Os = clientInfo.OS.ToString(),
LoginIp = ipAddr,
LoginLocation = location.Province + "-" + location.City
};
return entity;
}
}
}

View File

@@ -12,6 +12,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Hei.Captcha" Version="0.3.0" />
<PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="UAParser" Version="3.1.47" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\framework\Yi.Framework.Data\Yi.Framework.Data.csproj" />

View File

@@ -16,6 +16,9 @@
</ItemGroup>
<ItemGroup>
<None Update="ip2region.db">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="key.pem">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>