Skip to content

Commit

Permalink
feat(auth): 优化AuthController.GetAuthInfo方法的实现 #227
Browse files Browse the repository at this point in the history
  • Loading branch information
gmf520 committed Apr 2, 2021
1 parent 9ff4b41 commit ba33738
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 73 deletions.
86 changes: 25 additions & 61 deletions samples/web/Liuliu.Demo.Web/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,81 +54,45 @@ public bool CheckUrlAuth(string url)

/// <summary>
/// 获取授权信息
/// </summary>
/// 步骤:
/// 1.获取初始化时缓存的所有ModuleInfo信息,此信息已经包含最新版本的Module->Function[]信息
/// 2.判断当前用户对于Function的权限
/// 3.提取有效的模块代码节点
/// </summary>
/// <returns>权限节点</returns>
[HttpGet]
[ModuleInfo]
[Description("获取授权信息")]
public List<string> GetAuthInfo()
public string[] GetAuthInfo()
{
Module[] modules = _functionAuthManager.Modules.ToArray();
List<AuthItem> list = new List<AuthItem>();
foreach (Module module in modules)
IServiceProvider provider = HttpContext.RequestServices;
IModuleHandler moduleHandler = provider.GetRequiredService<IModuleHandler>();
IFunctionAuthorization functionAuthorization = provider.GetService<IFunctionAuthorization>();
ModuleInfo[] moduleInfos = moduleHandler.ModuleInfos;

//先查找出所有有权限的模块
List<ModuleInfo> authModules = new List<ModuleInfo>();
foreach (ModuleInfo moduleInfo in moduleInfos)
{
if (CheckFuncAuth(module, out bool empty))
{
list.Add(new AuthItem { Code = GetModuleTreeCode(module, modules), HasFunc = !empty });
}
}
List<string> codes = new List<string>();
foreach (AuthItem item in list)
{
if (item.HasFunc)
{
codes.Add(item.Code);
}
else if (list.Any(m => m.Code.Length > item.Code.Length && m.Code.Contains(item.Code) && m.HasFunc))
bool hasAuth = moduleInfo.DependOnFunctions.All(m => functionAuthorization.Authorize(m, User).IsOk);
if (moduleInfo.DependOnFunctions.Length == 0 || hasAuth)
{
codes.Add(item.Code);
authModules.Add(moduleInfo);
}
}
return codes;
}

/// <summary>
/// 验证是否拥有指定模块的权限
/// </summary>
/// <param name="module">要验证的模块</param>
/// <param name="empty">返回模块是否为空模块,即是否分配有功能</param>
/// <returns></returns>
private bool CheckFuncAuth(Module module, out bool empty)
{
IServiceProvider services = HttpContext.RequestServices;
IFunctionAuthorization authorization = services.GetService<IFunctionAuthorization>();

Function[] functions = _functionAuthManager.ModuleFunctions.Where(m => m.ModuleId == module.Id).Select(m => m.Function).ToArray();
empty = functions.Length == 0;
if (empty)
{
return true;
}

foreach (Function function in functions)
List<string> codes = new List<string>();
foreach (ModuleInfo moduleInfo in authModules)
{
if (!authorization.Authorize(function, User).IsOk)
string fullCode = moduleInfo.FullCode;
//模块下边有功能,或者拥有子模块
if (moduleInfo.DependOnFunctions.Length > 0
|| authModules.Any(m => m.FullCode.Length > fullCode.Length && m.FullCode.Contains(fullCode) && m.DependOnFunctions.Length > 0))
{
return false;
codes.AddIfNotExist(fullCode);
}
}
return true;
}

/// <summary>
/// 获取模块的树形路径代码串
/// </summary>
private static string GetModuleTreeCode(Module module, Module[] source)
{
var pathIds = module.TreePathIds;
string[] names = pathIds.Select(m => source.First(n => n.Id == m)).Select(m => m.Code).ToArray();
return names.ExpandAndToString(".");
}


private class AuthItem
{
public string Code { get; set; }

public bool HasFunc { get; set; }
return codes.ToArray();
}
}
}
9 changes: 8 additions & 1 deletion src/OSharp.Authorization.Functions/ModuleHandlerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,19 @@ protected ModuleHandlerBase(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
_moduleInfoPicker = serviceProvider.GetService<IModuleInfoPicker>();
Logger = serviceProvider.GetLogger(GetType());
ModuleInfos = new ModuleInfo[0];
}

/// <summary>
/// 获取 日志记录对象
/// </summary>
protected ILogger Logger { get; }

/// <summary>
/// 获取 所有模块信息
/// </summary>
public ModuleInfo[] ModuleInfos { get; private set; }

/// <summary>
/// 从程序集中获取模块信息
/// </summary>
Expand All @@ -67,8 +73,9 @@ public void Initialize()
{
SyncToDatabase(provider, moduleInfos);
});
ModuleInfos = moduleInfos.OrderBy(m => $"{m.Position}.{m.Code}").ToArray();
}

/// <summary>
/// 重写以实现将提取到的模块信息同步到数据库中
/// </summary>
Expand Down
49 changes: 38 additions & 11 deletions src/OSharp.Hosting.Apis/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

using OSharp.AspNetCore.Mvc;
using OSharp.AspNetCore.Mvc.Filters;
using OSharp.Authorization;
using OSharp.Authorization.Modules;
using OSharp.Hosting.Authorization;
using OSharp.Collections;


namespace OSharp.Hosting.Apis.Controllers
Expand All @@ -25,13 +28,6 @@ namespace OSharp.Hosting.Apis.Controllers
[ModuleInfo(Order = 2)]
public class AuthController : SiteApiControllerBase
{
private readonly FunctionAuthManager _functionAuthManager;

public AuthController(FunctionAuthManager functionAuthManager)
{
_functionAuthManager = functionAuthManager;
}

/// <summary>
/// 检查URL授权
/// </summary>
Expand All @@ -48,14 +44,45 @@ public bool CheckUrlAuth(string url)

/// <summary>
/// 获取授权信息
/// </summary>
/// 步骤:
/// 1.获取初始化时缓存的所有ModuleInfo信息,此信息已经包含最新版本的Module->Function[]信息
/// 2.判断当前用户对于Function的权限
/// 3.提取有效的模块代码节点
/// </summary>
/// <returns>权限节点</returns>
[HttpGet]
[ModuleInfo]
[Description("获取授权信息")]
public List<string> GetAuthInfo()
public string[] GetAuthInfo()
{
throw new NotImplementedException();
IServiceProvider provider = HttpContext.RequestServices;
IModuleHandler moduleHandler = provider.GetRequiredService<IModuleHandler>();
IFunctionAuthorization functionAuthorization = provider.GetService<IFunctionAuthorization>();
ModuleInfo[] moduleInfos = moduleHandler.ModuleInfos;

//先查找出所有有权限的模块
List<ModuleInfo> authModules = new List<ModuleInfo>();
foreach (ModuleInfo moduleInfo in moduleInfos)
{
bool hasAuth = moduleInfo.DependOnFunctions.All(m => functionAuthorization.Authorize(m, User).IsOk);
if (moduleInfo.DependOnFunctions.Length == 0 || hasAuth)
{
authModules.Add(moduleInfo);
}
}

List<string> codes = new List<string>();
foreach (ModuleInfo moduleInfo in authModules)
{
string fullCode = moduleInfo.FullCode;
//模块下边有功能,或者拥有子模块
if (moduleInfo.DependOnFunctions.Length > 0
|| authModules.Any(m => m.FullCode.Length > fullCode.Length && m.FullCode.Contains(fullCode) && m.DependOnFunctions.Length > 0))
{
codes.AddIfNotExist(fullCode);
}
}
return codes.ToArray();
}
}
}
5 changes: 5 additions & 0 deletions src/OSharp/Authorization/Modules/IModuleHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ namespace OSharp.Authorization.Modules
/// </summary>
public interface IModuleHandler
{
/// <summary>
/// 获取 所有模块信息
/// </summary>
ModuleInfo[] ModuleInfos { get; }

/// <summary>
/// 从程序集中获取模块信息
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/OSharp/Authorization/Modules/ModuleInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public class ModuleInfo : IEntityHash
/// </summary>
public string PositionName { get; set; }

/// <summary>
/// 获取 位置全名
/// </summary>
public string FullCode => $"{Position}.{Code}";

/// <summary>
/// 获取或设置 依赖功能
/// </summary>
Expand Down

0 comments on commit ba33738

Please sign in to comment.