Help us improve
Share bugs, ideas, or general feedback.
From ABP Sensei
Defines and checks permissions in ABP Framework v10.4 using PermissionDefinitionProvider, [Authorize], CheckPolicyAsync, and IPermissionManager. Covers role-based and resource-based authorization.
npx claudepluginhub burakdmir/abp-skills --plugin abp-senseiHow this skill is triggered — by the user, by Claude, or both
Slash command
/abp-sensei:abp-authorizationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
User asks about permissions, authorization, roles, policies, permission groups, resource-based authorization, or access control in ABP Framework.
Applies C++ Core Guidelines to write, review, or refactor C++ code. Enforces modern, safe, and idiomatic practices for C++17/20/23.
Share bugs, ideas, or general feedback.
User asks about permissions, authorization, roles, policies, permission groups, resource-based authorization, or access control in ABP Framework.
ABP extends ASP.NET Core Authorization with a Permission System that auto-registers permissions as policies. Two permission types exist:
Create a class inheriting PermissionDefinitionProvider:
using Volo.Abp.Authorization.Permissions;
namespace Acme.BookStore.Permissions
{
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var myGroup = context.AddGroup(
"BookStore",
LocalizableString.Create<BookStoreResource>("BookStore")
);
myGroup.AddPermission(
"BookStore_Author_Create",
LocalizableString.Create<BookStoreResource>("Permission:BookStore_Author_Create")
);
}
}
}
Application.Contracts projectcontext.AddGroup("GroupName") creates a new groupLocalizableString.Create<TResource>("Key") for localized display namesmyGroup.AddPermission(
"BookStore_Books_Manage",
LocalizableString.Create<BookStoreResource>("Permission:ManageBooks"),
multiTenancySide: MultiTenancySides.Tenant // Host, Tenant, or Both (default)
);
Multi-tenancy side options:
MultiTenancySides.Host — Available only on host sideMultiTenancySides.Tenant — Available only on tenant sideMultiTenancySides.Both (default) — Available on bothPermissions can have parent-child relationships for hierarchical UI display:
var booksPermission = myGroup.AddPermission("BookStore_Books_Manage");
booksPermission.AddChild("BookStore_Books_Create");
booksPermission.AddChild("BookStore_Books_Edit");
booksPermission.AddChild("BookStore_Books_Delete");
myGroup.AddPermission("BookStore_Feature", isEnabled: false); // Disabled by default
// Depending on Features
myGroup.AddPermission("BookStore_Advanced")
.WithFeatureDependency("AdvancedFeature");
// Depending on Global Features
myGroup.AddPermission("BookStore_Preview")
.WithGlobalFeatureDependency("PreviewModule");
// Custom condition
myGroup.AddPermission("BookStore_Special")
.WithStateChecker(() => MyStaticChecker.IsSpecialEnabled);
myGroup.AddPermission("BookStore_Special")
.WithPolicyDependency(new MyCustomPolicyRequirement());
[DependsOn(typeof(AbpIdentityModule))]
public class MyModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<PermissionDefinitionContext>(options =>
{
// Modify identity module permissions before they're finalized
});
}
}
[Authorize("BookStore_Author_Create")]
public async Task<IActionResult> CreateAsync(CreateAuthorDto input)
{
// ...
}
public class AuthorAppService : ApplicationService, IAuthorAppService
{
public async Task<AuthorDto> CreateAsync(CreateAuthorDto input)
{
await AuthorizationService.CheckAsync("BookStore_Author_Create");
// or
if (!await AuthorizationService.IsGrantedAsync("BookStore_Author_Create"))
{
throw new AbpAuthorizationException("...");
}
// ...
}
}
public class MyService : ITransientDependency
{
private readonly IAuthorizationService _authorizationService;
public MyService(IAuthorizationService authorizationService)
{
_authorizationService = authorizationService;
}
public async Task DoWorkAsync()
{
await _authorizationService.CheckAsync("BookStore_Author_Create");
}
}
Shortcut methods in base classes:
await CheckPolicyAsync("...")(throws an exception if not granted) andawait IsGrantedAsync("...")(returns a bool, does not throw).
Authenticated user information is accessed via the CurrentUser property — it is available out of the box in base classes (ApplicationService, DomainService, AbpController) and requires no injection:
public class BookAppService : ApplicationService
{
public async Task DoSomethingAsync()
{
var userId = CurrentUser.Id; // Guid?
var userName = CurrentUser.UserName;
var email = CurrentUser.Email;
var isAuth = CurrentUser.IsAuthenticated;
var roles = CurrentUser.Roles;
var tenantId = CurrentUser.TenantId;
}
}
// Inject ICurrentUser in services that don't derive from a base class
public class MyService : ITransientDependency
{
private readonly ICurrentUser _currentUser;
public MyService(ICurrentUser currentUser) => _currentUser = currentUser;
}
public async Task UpdateMyBookAsync(Guid bookId, UpdateBookDto input)
{
var book = await _bookRepository.GetAsync(bookId);
if (book.CreatorId != CurrentUser.Id)
{
throw new AbpAuthorizationException();
}
// update...
}
Security: never trust client input for the user identity — always use
CurrentUserand verify ownership inside the application service.
For fine-grained, per-instance permissions:
// Define a resource permission
var booksGroup = context.AddGroup("BookStore_Books");
var bookPermission = booksGroup.AddResourcePermission(
"BookStore_Books_Edit",
typeof(Book),
LocalizableString.Create<BookStoreResource>("Permission:EditBook")
);
Resource-based permissions are managed through the Resource Permission Management Dialog on individual resource instances (not the global permissions dialog).
See: Resource-Based Authorization
ISettingManager or the Identity module UIModuleName_Entity_Action (e.g., BookStore_Books_Create)LocalizableString.Create<TResource>()var books = myGroup.AddPermission("BookStore_Books_Manage");
books.AddChild("BookStore_Books_Create");
books.AddChild("BookStore_Books_Edit");
books.AddChild("BookStore_Books_Delete");
books.AddChild("BookStore_Books_ViewList");
public abstract class BookStoreAppService : ApplicationService
{
protected BookStoreAppService()
{
LocalizationResource = typeof(BookStoreResource);
}
protected virtual async Task CheckPolicyAsync(string policyName)
{
await AuthorizationService.CheckAsync(policyName);
}
}