C# 从声明中检查ABP权限
我正在为ASP.NET核心使用ABP 3.9版。我们有一个现有的Identity Server 4实例,它以声明的形式(通过OIDC)提供角色信息。我想连接到ABP的权限系统中,以实现动态菜单设置和其他功能。因为我没有使用本地1实现,所以我看不到将声明转换为权限的方法 我的想法是使用自定义中间件来处理它,如下所示:C# 从声明中检查ABP权限,c#,asp.net-core,authorization,aspnetboilerplate,claims,C#,Asp.net Core,Authorization,Aspnetboilerplate,Claims,我正在为ASP.NET核心使用ABP 3.9版。我们有一个现有的Identity Server 4实例,它以声明的形式(通过OIDC)提供角色信息。我想连接到ABP的权限系统中,以实现动态菜单设置和其他功能。因为我没有使用本地1实现,所以我看不到将声明转换为权限的方法 我的想法是使用自定义中间件来处理它,如下所示: public class ClaimsToAbpPermissionsMiddleware { private readonly RequestDelegate _next;
public class ClaimsToAbpPermissionsMiddleware
{
private readonly RequestDelegate _next;
public ClaimsToAbpPermissionsMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// Get user
ClaimsPrincipal user = context.User;
// foreach claim of type "role"
var roleClaims = user.Claims.Where(claim => claim.Type == "role");
foreach (Claim claim in roleClaims)
{
switch (claim.Value)
{
case "TestResults":
// Assign applicable permission
// ...
break;
default:
break;
}
}
// Call the next delegate/middleware in the pipeline
await _next(context);
}
}
问题是我不知道如何应用权限。2建议使用UserManager
,它似乎具有必要的功能
首先,Abp.ZeroCore
没有这个类。我可以在ASP.NET核心应用程序中使用Abp.Zero
其次,它看起来像Abp.Authorization.Users.AbpUserManager
具有类似的功能。我能用这个吗?但是,我不确定如何将其注入启动
,因为它需要一些类型来注入AbpUserManager
,我不清楚使用什么类型
任何帮助都将不胜感激。
此外,我正在尝试的是可行的吗?有更好的方法吗
问题是我没有使用模块0的2。我们所有的用户都在一个单独的ASP.NET Identity(Identity Server)实现中,我使用的是来自ABP的模板,它不包括用户/租户/角色的模型/页面,因此我没有要注入的类型AbpUserManager
1二, 更新:所以我按照下面的答案实现了IPermissionChecker: PermissionChecker(不喜欢这个开关,但一旦它工作起来,我将进行重构): 模块初始化:
public class CentralPortalCoreModule : AbpModule
{
public override void PreInitialize()
{
Configuration.Auditing.IsEnabledForAnonymousUsers = true;
CentralPortalLocalizationConfigurer.Configure(Configuration.Localization);
IocManager.Register<IPermissionChecker, PermissionChecker>(DependencyLifeStyle.Transient);
Configuration.Authorization.Providers.Add<MyAuthProvider>();
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(CentralPortalCoreModule).GetAssembly());
}
}
添加断点表明PermissionChecker与AuthProvider一样初始化。不幸的是,即使我已通过身份验证并拥有有效的角色声明,导航也不会显示受保护的项目。从未调用IsGrantedAsync方法。我尝试将导航项设置为requireAuthentication=true和false,但都没有改变任何内容
我遗漏了什么吗?好吧,您指的是模块零文档,但没有使用模块零 如果不存储用户,则存储用户权限可能没有意义 您可以实现
IPermissionChecker
来检查来自声明的权限
公共类PermissionChecker:IPermissionChecker,ITransientDependency
{
专用只读IHttpContextAccessor\u httpContextAccessor;
公共权限检查器(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor=httpContextAccessor;
}
公共异步任务IsGrantedAsync(字符串permissionName)
{
//获取用户
var user=\u httpContextAccessor.HttpContext.user;
//获取“角色”类型的声明
var roleClaims=user.Claims.Where(claim=>claim.Type==“role”);
//根据角色权限检查适用的权限
// ...
}
公共任务IsGrantedAsync(UserIdentifier用户,字符串permissionName)
{
返回IsGrantedAsync(permissionName);
}
}
由于AuthorizationHelper
检查AbpSession.UserId
,因此必须重写其方法
public class NonUserAuthorizationHelper : AuthorizationHelper
{
private readonly IAuthorizationConfiguration _authConfiguration
public NonUserAuthorizationHelper(IFeatureChecker featureChecker, IAuthorizationConfiguration authConfiguration)
: base(featureChecker, authConfiguration)
{
_authConfiguration = authConfiguration;
}
public override async Task AuthorizeAsync(IEnumerable<IAbpAuthorizeAttribute> authorizeAttributes)
{
if (!_authConfiguration.IsEnabled)
{
return;
}
// if (!AbpSession.UserId.HasValue)
// {
// throw new AbpAuthorizationException(
// LocalizationManager.GetString(AbpConsts.LocalizationSourceName, "CurrentUserDidNotLoginToTheApplication")
// );
// }
foreach (var authorizeAttribute in authorizeAttributes)
{
await PermissionChecker.AuthorizeAsync(authorizeAttribute.RequireAllPermissions, authorizeAttribute.Permissions);
}
}
}
好的,您指的是模块0文档,但不是使用模块0 如果不存储用户,则存储用户权限可能没有意义 您可以实现
IPermissionChecker
来检查来自声明的权限
公共类PermissionChecker:IPermissionChecker,ITransientDependency
{
专用只读IHttpContextAccessor\u httpContextAccessor;
公共权限检查器(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor=httpContextAccessor;
}
公共异步任务IsGrantedAsync(字符串permissionName)
{
//获取用户
var user=\u httpContextAccessor.HttpContext.user;
//获取“角色”类型的声明
var roleClaims=user.Claims.Where(claim=>claim.Type==“role”);
//根据角色权限检查适用的权限
// ...
}
公共任务IsGrantedAsync(UserIdentifier用户,字符串permissionName)
{
返回IsGrantedAsync(permissionName);
}
}
由于AuthorizationHelper
检查AbpSession.UserId
,因此必须重写其方法
public class NonUserAuthorizationHelper : AuthorizationHelper
{
private readonly IAuthorizationConfiguration _authConfiguration
public NonUserAuthorizationHelper(IFeatureChecker featureChecker, IAuthorizationConfiguration authConfiguration)
: base(featureChecker, authConfiguration)
{
_authConfiguration = authConfiguration;
}
public override async Task AuthorizeAsync(IEnumerable<IAbpAuthorizeAttribute> authorizeAttributes)
{
if (!_authConfiguration.IsEnabled)
{
return;
}
// if (!AbpSession.UserId.HasValue)
// {
// throw new AbpAuthorizationException(
// LocalizationManager.GetString(AbpConsts.LocalizationSourceName, "CurrentUserDidNotLoginToTheApplication")
// );
// }
foreach (var authorizeAttribute in authorizeAttributes)
{
await PermissionChecker.AuthorizeAsync(authorizeAttribute.RequireAllPermissions, authorizeAttribute.Permissions);
}
}
}
谢谢关于零模块,你是对的。文件中不清楚两者之间的区别。显然,只有在下载模板时选择用户资料时,它才会被包括在内?您知道我是否可以利用该模型的菜单(RequiredPermissionName)是的,只需实现
IPermissionChecker
。非常好。谢谢我自己重写它来处理权限检查,但这是最好的解决方案。谢谢!关于零模块,你是对的。文件中不清楚两者之间的区别。显然,只有在下载模板时选择用户资料时,它才会被包括在内?您知道我是否可以利用该模型的菜单(RequiredPermissionName)是的,只需实现IPermissionChecker
。非常好。谢谢我自己重写它来处理权限检查,但这是最好的解决方案。
public override void SetNavigation(INavigationProviderContext context)
{
context.Manager.MainMenu
.AddItem(
new MenuItemDefinition(
PageNames.Home,
L("HomePage"),
url: "",
icon: "fa fa-home"
)
).AddItem(
new MenuItemDefinition(
PageNames.About,
L("About"),
url: "Home/About",
icon: "fa fa-info",
requiredPermissionName: "AboutView",
requiresAuthentication: true
)
).AddItem(
new MenuItemDefinition(
"Results",
L("Results"),
url: "Results",
icon: "fa fa-tasks",
requiredPermissionName: "TestResults"
)
)
.AddItem(
new MenuItemDefinition(
PageNames.Account,
L("Account"),
url: "Account",
icon: "fa fa-info",
requiredPermissionName:"AccountView",
requiresAuthentication: true
)
)
.AddItem(
new MenuItemDefinition(
PageNames.Contact,
L("Contact"),
url: "Contact",
icon: "fa fa-info"
)
);
}
public class NonUserAuthorizationHelper : AuthorizationHelper
{
private readonly IAuthorizationConfiguration _authConfiguration
public NonUserAuthorizationHelper(IFeatureChecker featureChecker, IAuthorizationConfiguration authConfiguration)
: base(featureChecker, authConfiguration)
{
_authConfiguration = authConfiguration;
}
public override async Task AuthorizeAsync(IEnumerable<IAbpAuthorizeAttribute> authorizeAttributes)
{
if (!_authConfiguration.IsEnabled)
{
return;
}
// if (!AbpSession.UserId.HasValue)
// {
// throw new AbpAuthorizationException(
// LocalizationManager.GetString(AbpConsts.LocalizationSourceName, "CurrentUserDidNotLoginToTheApplication")
// );
// }
foreach (var authorizeAttribute in authorizeAttributes)
{
await PermissionChecker.AuthorizeAsync(authorizeAttribute.RequireAllPermissions, authorizeAttribute.Permissions);
}
}
}
// using Abp.Configuration.Startup;
public override void PreInitialize()
{
Configuration.ReplaceService<IAuthorizationHelper, NonUserAuthorizationHelper>();
}