--- description: "ABP permission system and authorization patterns" globs: - "**/*Permission*.cs" - "**/*AppService*.cs" - "**/*Controller*.cs" alwaysApply: false --- # ABP Authorization > **Docs**: https://abp.io/docs/latest/framework/fundamentals/authorization ## Permission Definition Define permissions in `*.Application.Contracts` project: ```csharp public static class BookStorePermissions { public const string GroupName = "BookStore"; public static class Books { public const string Default = GroupName + ".Books"; public const string Create = Default + ".Create"; public const string Edit = Default + ".Edit"; public const string Delete = Default + ".Delete"; } } ``` Register in provider: ```csharp public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider { public override void Define(IPermissionDefinitionContext context) { var bookStoreGroup = context.AddGroup(BookStorePermissions.GroupName, L("Permission:BookStore")); var booksPermission = bookStoreGroup.AddPermission( BookStorePermissions.Books.Default, L("Permission:Books")); booksPermission.AddChild( BookStorePermissions.Books.Create, L("Permission:Books.Create")); booksPermission.AddChild( BookStorePermissions.Books.Edit, L("Permission:Books.Edit")); booksPermission.AddChild( BookStorePermissions.Books.Delete, L("Permission:Books.Delete")); } private static LocalizableString L(string name) { return LocalizableString.Create(name); } } ``` ## Using Permissions ### Declarative (Attribute) ```csharp [Authorize(BookStorePermissions.Books.Create)] public virtual async Task CreateAsync(CreateBookDto input) { // Only users with Books.Create permission can execute } ``` ### Programmatic Check ```csharp public class BookAppService : ApplicationService { public async Task DoSomethingAsync() { // Check and throw if not granted await CheckPolicyAsync(BookStorePermissions.Books.Edit); // Or check without throwing if (await IsGrantedAsync(BookStorePermissions.Books.Delete)) { // Has permission } } } ``` ### Allow Anonymous Access ```csharp [AllowAnonymous] public virtual async Task GetPublicBookAsync(Guid id) { // No authentication required } ``` ## Current User Access authenticated user info via `CurrentUser` property (available in base classes like `ApplicationService`, `DomainService`, `AbpController`): ```csharp public class BookAppService : ApplicationService { public async Task DoSomethingAsync() { // CurrentUser is available from base class - no injection needed var userId = CurrentUser.Id; var userName = CurrentUser.UserName; var email = CurrentUser.Email; var isAuthenticated = CurrentUser.IsAuthenticated; var roles = CurrentUser.Roles; var tenantId = CurrentUser.TenantId; } } // In other services, inject ICurrentUser public class MyService : ITransientDependency { private readonly ICurrentUser _currentUser; public MyService(ICurrentUser currentUser) => _currentUser = currentUser; } ``` ### Ownership Validation ```csharp public async Task UpdateMyBookAsync(Guid bookId, UpdateBookDto input) { var book = await _bookRepository.GetAsync(bookId); if (book.CreatorId != CurrentUser.Id) { throw new AbpAuthorizationException(); } // Update book... } ``` ## Multi-Tenancy Permissions Control permission availability per tenant side: ```csharp bookStoreGroup.AddPermission( BookStorePermissions.Books.Default, L("Permission:Books"), multiTenancySide: MultiTenancySides.Tenant // Only for tenants ); ``` Options: `MultiTenancySides.Host`, `Tenant`, or `Both` ## Feature-Dependent Permissions ```csharp booksPermission.RequireFeatures("BookStore.PremiumFeature"); ``` ## Permission Management Grant/revoke permissions programmatically: ```csharp public class MyService : ITransientDependency { private readonly IPermissionManager _permissionManager; public async Task GrantPermissionToUserAsync(Guid userId, string permissionName) { await _permissionManager.SetForUserAsync(userId, permissionName, true); } public async Task GrantPermissionToRoleAsync(string roleName, string permissionName) { await _permissionManager.SetForRoleAsync(roleName, permissionName, true); } } ``` ## Security Best Practices - Never trust client input for user identity - Use `CurrentUser` property (from base class) or inject `ICurrentUser` - Validate ownership in application service methods - Filter queries by current user when appropriate - Don't expose sensitive fields in DTOs