{"id":21954815,"url":"https://github.com/mgernand/aspnetcore.authorization.permissions","last_synced_at":"2025-08-21T12:30:51.819Z","repository":{"id":38299883,"uuid":"487357952","full_name":"mgernand/AspNetCore.Authorization.Permissions","owner":"mgernand","description":"A libary that provides permission-based authorization.","archived":false,"fork":false,"pushed_at":"2024-04-18T10:27:33.000Z","size":1413,"stargazers_count":40,"open_issues_count":3,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-05-18T12:46:59.759Z","etag":null,"topics":["asp-net-core","authentication","authorization","dotnet","dotnet-core","multi-tenancy","multi-tenant","permissions","tenant"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mgernand.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-30T18:55:48.000Z","updated_at":"2024-06-02T12:47:30.627Z","dependencies_parsed_at":"2024-06-02T12:47:28.188Z","dependency_job_id":"b3b82f95-80d5-4b5d-95c2-a660cfc4e56f","html_url":"https://github.com/mgernand/AspNetCore.Authorization.Permissions","commit_stats":{"total_commits":35,"total_committers":2,"mean_commits":17.5,"dds":0.2857142857142857,"last_synced_commit":"305978444d5e3ddeed7789c8fb2c2be907a71006"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FAspNetCore.Authorization.Permissions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FAspNetCore.Authorization.Permissions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FAspNetCore.Authorization.Permissions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FAspNetCore.Authorization.Permissions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mgernand","download_url":"https://codeload.github.com/mgernand/AspNetCore.Authorization.Permissions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230511479,"owners_count":18237657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp-net-core","authentication","authorization","dotnet","dotnet-core","multi-tenancy","multi-tenant","permissions","tenant"],"created_at":"2024-11-29T07:26:11.904Z","updated_at":"2025-08-21T12:30:51.806Z","avatar_url":"https://github.com/mgernand.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AspNetCore.Authorization.Permissions\n\nA libary that provides permission-based authorization.\n\n## This repository was moved to https://codeberg.org/mgernand/AspNetCore.Authorization.Permissions\n\nThe ASP.NET Core role-based authorization in combination with custom authorization policies\nis a good starting point for restricting users' access in an application, but it is very \nstatic and changes to the meaning of a role or a policy forces you to perform changes in \nyour code and to re-deploy your application. This library aims to overcome this limitation.\n\nTo be able to dynamically change the access of a user we extend the role in a way that each\nrole is made up of several fine gained permissions. Throughout the documentation and the \nsample applications we will use the following roles and permissions.\n\n| Role          | Invoice.Read | Invoice.Write | Invoice.Delete | Invoice.Send | Invoice.Payment |\n|---------------|--------------|---------------|----------------|--------------|-----------------|\n| Boss          | **YES**      | NO            | NO             | NO           | NO              |\n| Manager       | **YES**      | NO            | **YES**        | NO           | NO              |\n| Employee      | **YES**      | **YES**       | NO             | **YES**      | **YES**         |\n\nIn this fictional company the boss can only read invoices, the manager can read and delete invoices and\nthe employees can read, write, send invocies and can trigger the selllement of the invoice.\n\nIf we build the authentication around the three role we will hard-code the access permissions in our\ncodebase f.e. using the ```[Authorize]``` attribute. But if the boss decides he also wants\nto be able to delete invoices, we need to change it in the source code.\n\nUsing permissions of the role defined in the table above in the ```[Authorize]``` attribute instead\nof the roles, we can just change the role configuration in a data store and assign the permision\n**_Invoices.Delete_** to the role **_Boss_**. The boss used is then able to delete invocies without\nthe need to change the code and re-deploy the application.\n\nThe library consists of two parts: \n\n1. The base definitions, policies and services to be able to check an authenticated users claims \n   (i.e. ```ClaimsPrincipal```) for asigned permissions.\n2. An implementation of the permissions API to work with ASP.NET Core Identity.\n\nIt is possible to add different storages and claims providers. A library that wanst to provide\nthe permissions claims just needs to implement the ```IClaimsProvider``` interface and the storage\nmechanism of course.\n\nIn addition to the basic permissions of users, this library provides an optional multi-tenant feature. \nThis feature allows assign tenants to users. The tenant infosmations are then added to the user's\nclaims. Storage systems can then leverage the tenant information to alter queries (Single Database with\nTenant Column) or to select connection strings (Tenant per Database).\n\nA tenant may have several roles and the permissions of those roles are added to the user's permission\nclaims. In that way additional permissions can be added to individual claims. The tenant sample applications\nprovide tenants with a distict tenant role assigned which provide the following additional tenant permissions.\nEach tenant represents a separate company. The roles in this example represent different plans of a\nSaaS application.\n\n| Role           | Invoice.Statistics | Invoice.TaxExport |\n|----------------|--------------------|-------------------|\n| Free           | NO                 | NO                |\n| Basic          | **YES**            | NO                |\n| Professional   | **YES**            | **YES**           |\n\nUsing tenants, roles and permissions is a good way to define differnent sets of features, f.e. when creating\ndifferent plans of a SaaS application.\n\n## Permission Usage\n\nTo configure the permissions with ASP.NET Identity and the default identity models add the following\ncode to your application startup code. The example uses EF Core and SQLite to store the Identity models.\n\nThe users, roles and permissions are added to the storage using the ```ApplicationDbContext``` and EF \nCore migrations. The code is omitted in this document, but you can look it up in the samples code.\n\n```C#\n// Previous service configuration omitted.\n\nbuilder.Services.AddControllers();\nbuilder.Services.AddRazorPages();\n\nbuilder.Services.AddAuthorization();\nbuilder.Services.AddPermissionsAuthorization();\n\nbuilder.Services\n\t.AddAuthentication(IdentityConstants.ApplicationScheme)\n\t.AddIdentityCookies();\n\nbuilder.Services\n\t.AddDbContext\u003cInvoicesContext\u003e(options =\u003e\n\t{\n\t\toptions.UseSqlite(\"Filename=permissions.db\");\n\t})\n\t.AddPermissionsIdentityCore\u003cIdentityUser, IdentityRole, IdentityPermission\u003e()\n\t.AddDefaultUI()\n\t.AddDefaultTokenProviders()\n\t.AddPermissionClaimsProvider()\n\t.AddUserManager\u003cAspNetUserManager\u003cIdentityUser\u003e\u003e()\n\t.AddRoleManager\u003cAspNetRoleManager\u003cIdentityRole\u003e\u003e()\n\t.AddPermissionManager\u003cAspNetPermissionManager\u003cIdentityPermission\u003e\u003e()\n\t.AddPermissionsEntityFrameworkStores\u003cInvoicesContext\u003e();\n\n// Additional service configuration omitted.\n```\n\n### Restrict access based on permissions\n\nThere are several ways to rescript access in your application.\n\n1. Use the ```[RequirePermission]``` attribute to restrict access to controller actions.\n2. Use the ```HasPermission()``` extension method with a ```ClaimsPrincipal``` instance.\n3. Use the ```HasPermission()``` method of a ```IUserPermissionsService``` instance.\n4. Use the ```RequirePermission``` extension methods for Minimal API endpoints.\n\nTo retrict the access to an action methods just add the ```[Authorize]``` attribute with the permission\nname as contraint.\n\n```C#\n// ASP.NET MVC controller action with attribute.\n[HttpGet]\n[HasPermission(\"Invoice.Payment\")]\npublic IActionResult Get()\n{\n\treturn this.Ok();\n}\n\n// Razor Pages with attribute.\n[HasPermission(\"Invoices.Read\")]\npublic class InvoicesReadModel : PageModel\n{\n\tpublic void OnGet()\n\t{\n\t}\n}\n\n// Razor Pages with extension method.\npublic class InvoicesReadModel : PageModel\n{\n\tpublic IActionResult OnGet()\n\t{\n\t\tif(!this.User.HasPermission(\"Invoice.Read\"))\n\t\t{\n\t\t\tif(this.User.IsAuthenticated())\n\t\t\t{\n\t\t\t\treturn this.Forbid();\n\t\t\t}\n\n\t\t\treturn this.Challenge();\n\t\t}\n\n\t\treturn this.Page();\n\t}\n}\n\n// Minimal API with extension method.\napp.MapGet(\"invoices/statistics\", (HttpContext context) =\u003e\n{\n\treturn Results.Ok();\n})\n.RequirePermission(\"Invoice.Statistics\");\n```\n\n## Tenant Usage\n\n```C#\n// Previous service configuration omitted.\n\nbuilder.Services.AddControllers();\nbuilder.Services.AddRazorPages();\n\nbuilder.Services.AddAuthorization();\nbuilder.Services.AddPermissionsAuthorization();\n\nbuilder.Services\n\t.AddAuthentication(IdentityConstants.ApplicationScheme)\n\t.AddIdentityCookies();\n\nbuilder.Services\n\t.AddDbContext\u003cInvoicesContext\u003e(options =\u003e\n\t{\n\t\toptions.UseSqlite(\"Filename=permissions.db\");\n\t})\n\t.AddPermissionsIdentityCore\u003cIdentityTenant, IdentityUser, IdentityRole, IdentityPermission\u003e()\n\t.AddDefaultUI()\n\t.AddDefaultTokenProviders()\n\t.AddIdentityClaimsProvider()\n\t.AddDefaultTenantProvider()\n\t.AddTenantManager\u003cAspNetTenantManager\u003cIdentityTenant\u003e\u003e()\n\t.AddUserManager\u003cAspNetTenantUserManager\u003cIdentityTenantUser\u003e\u003e()\n\t.AddRoleManager\u003cAspNetRoleManager\u003cIdentityRole\u003e\u003e()\n\t.AddPermissionManager\u003cAspNetPermissionManager\u003cIdentityPermission\u003e\u003e()\n\t.AddPermissionsEntityFrameworkStores\u003cInvoicesContext\u003e();\n\n// Additional service configuration omitted.\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgernand%2Faspnetcore.authorization.permissions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmgernand%2Faspnetcore.authorization.permissions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgernand%2Faspnetcore.authorization.permissions/lists"}