1- # Dynamic Role-Based Authorization in ASP.NET Core 2.2 and  3.x  [ ![ NuGet] ( http://img.shields.io/nuget/v/DynamicAuthorization.Mvc.Core.svg?style=flat )] ( https://www.nuget.org/packages/DynamicAuthorization.Mvc.Core )    
1+ # Dynamic Role-Based Authorization in ASP.NET Core MVC  2.2,  3.x and 5.0   [ ![ NuGet] ( http://img.shields.io/nuget/v/DynamicAuthorization.Mvc.Core.svg?style=flat )] ( https://www.nuget.org/packages/DynamicAuthorization.Mvc.Core )    
22
33You already know how role-based authorization works in ASP.NET Core.
44
@@ -11,22 +11,18 @@ public class AdministrationController : Controller
1111
1212But what if you don't want hardcode roles on the ` Authorize `  attribute or create roles later and specify in which controller and action it has access without touching source code?
1313
14- ** DynamicAuthorization**  helps you authorize users without hardcoding role(s) on the  ` Authorize `  attribute with minimum effort. DynamicAuthorization is built at the top of ASP.NET Core Identity and use identity mechanism for managing roles and authorizing users.
15- 
16- Install the _ DynamicAuthorization.Mvc.Core_  [ NuGet package] ( https://www.nuget.org/packages/DynamicAuthorization.Mvc.Core )  and _ DynamicAuthorization.Mvc.JsonStore_  [ NuGet package] ( https://www.nuget.org/packages/DynamicAuthorization.Mvc.JsonStore ) 
14+ ** DynamicAuthorization**  helps you authorize users without hardcoding role(s) on the  ` Authorize `  attribute with minimum effort. DynamicAuthorization is built at the top of ASP.NET Core Identity and uses identity mechanism for managing roles and authorizing users.
1715
16+ Install the _ DynamicAuthorization.Mvc.Core_  [ NuGet package] ( https://www.nuget.org/packages/DynamicAuthorization.Mvc.Core )  
1817``` powershell 
1918Install-Package DynamicAuthorization.Mvc.Core 
20- Install-Package DynamicAuthorization.Mvc.JsonStore 
2119``` 
2220or
2321``` shell 
2422dotnet add package DynamicAuthorization.Mvc.Core
25- dotnet add package DynamicAuthorization.Mvc.JsonStore
2623``` 
2724
28- Then, add ` AddDynamicAuthorization() `  to ` IServiceCollection `  in ` ConfigureServices `  method:
29- 
25+ Then, add ` AddDynamicAuthorization() `  to ` IServiceCollection `  in ` Startup.ConfigureServices `  method:
3026``` csharp 
3127public  void  ConfigureServices (IServiceCollection  services )
3228{
@@ -36,15 +32,137 @@ public void ConfigureServices(IServiceCollection services)
3632        .AddEntityFrameworkStores <ApplicationDbContext >()
3733        .AddDefaultTokenProviders ();
3834
35+     services 
36+         .AddDynamicAuthorization <ApplicationDbContext >(options  =>  options .DefaultAdminUser  =  " UserName"  )
37+ ```
38+ You  can  set  the  default  admin  username  via  `DefaultAdminUser ` config  to  access  everywhere  without  creating  a  default  admin  role  and  its  access .
39+ 
40+ Then  install  JSON  or  SQLSever  store  to  save  role  access .
41+ 
42+ To  install  _DynamicAuthorization .Mvc .JsonStore_  [NuGet  package ](https :// www.nuget.org/packages/DynamicAuthorization.Mvc.JsonStore)
43+  ```powershell 
44+ Install - Package  DynamicAuthorization .Mvc .JsonStore 
45+ ```
46+ or 
47+ ```shell 
48+ dotnet  add  package  DynamicAuthorization .Mvc .JsonStore 
49+ ```
50+ ```csharp 
51+ public  void  ConfigureServices (IServiceCollection  services )
52+ {
53+         
3954    services 
4055        .AddDynamicAuthorization <ApplicationDbContext >(options  =>  options .DefaultAdminUser  =  " UserName"  )
4156        .AddJsonStore (options  =>  options .FilePath  =  " FilePath"  );
4257```
58+ Role  access  will  be  saved  in  a  JSON  file  and  you  can  specify  the  file  path  `FilePath ` config .
59+ 
60+ Or  install  SQLServer  store  _DynamicAuthorization .Mvc .MsSqlServerStore_  [NuGet  package ](https :// www.nuget.org/packages/DynamicAuthorization.Mvc.MsSqlServerStore)
61+  ```powershell 
62+ Install - Package  DynamicAuthorization .Mvc .MsSqlServerStore 
63+ ```
64+ or 
65+ ```shell 
66+ dotnet  add  package  DynamicAuthorization .Mvc .MsSqlServerStore 
67+ ```
68+ ```csharp 
69+ public  void  ConfigureServices (IServiceCollection  services )
70+ {
71+         
72+     services 
73+         .AddDynamicAuthorization <ApplicationDbContext >(options  =>  options .DefaultAdminUser  =  " UserName"  )
74+         .AddSqlServerStore (options  =>  options .ConnectionString  =  " ConnectionString"  );
75+ ```
76+ 
77+ You  can  decorate  controllers  and  actions  with  `DisplayName ` attribute  to  show  the  user  a  more  meaningful  name  instead  of  controller  and  action  name .
78+ ```c #
79+ [DisplayName (" Access Management"  )]
80+ public  class  AccessController  :  Controller 
81+ {
4382
44- You  can  set  default  admin  username  via  `DefaultAdminUser ` config  to  access  everywhere  and  wihtout  needing  create  default  admin  role  and  it 's access.  
83+     //  GET: Access 
84+      [DisplayName (" Access List"  )]
85+     public  async  Task < ActionResult >  Index ()
86+ }
87+ ```
88+ 
89+ You  can  also  the  default  UI  for  managing  roles  and  assigning  roles  to  users  if  you  don 't want to implement them by yourself.  
90+ 
91+ Install  the  _DynamicAuthorization .Mvc .Ui_  [NuGet  package ](https :// www.nuget.org/packages/DynamicAuthorization.Mvc.Ui)
92+ 
93+ ```powershell 
94+ Install - Package  DynamicAuthorization .Mvc .Ui 
95+ ```
4596
46- Role  access  will  be  saved  in  JSON  file  and  you  can  specify  the  file  path  `FilePath ` config .
97+ Then  `AddUi ` to  DynamicAuthorization  registration :
98+ ```
99+ services 
100+         .AddDynamicAuthorization <ApplicationDbContext >(options  =>  options .DefaultAdminUser  =  " UserName"  )
101+         .AddJsonStore (options  =>  options .FilePath  =  " FilePath"  )
102+         .AddUi ();
103+ ```
104+ 
105+ Use  `/ role ` url  to  manage  roles  and  `/ userrole ` url  to  assign  roles  to  users .
106+ 
107+ ! [create  project ](https :// raw.githubusercontent.com/mo-esmp/DynamicRoleBasedAuthorizationNETCore/dev/assets/create-role-2.jpg)
108+ 
109+ You  can  also  use  a  custom  `TageHelper ` to  check  whether  the  user  has  access  to  view  content  or  not . create  a  custom  tag  helper  that  inherits  from  `SecureContentTagHelper `
110+ 
111+ ```c #
112+ [HtmlTargetElement (" secure-content"  )]
113+ public  class  MySecureContentTagHelper  : SecureContentTagHelper < ApplicationDbContext > 
114+ {
115+     public  MySecureContentTagHelper (
116+         ApplicationDbContext  dbContext ,
117+         DynamicAuthorizationOptions  authorizationOptions ,
118+         IRoleAccessStore  roleAccessStore 
119+         )
120+         :  base (dbContext , authorizationOptions , roleAccessStore )
121+     {
122+     }
123+ }
124+ ```
125+ 
126+ In  each  view  wrap  a  content  or  an  anchor  tag  inside  `secure - content ` tag :
127+ 
128+ ```html 
129+ < ul  class = " nav navbar-nav" > 
130+     < li >< a  asp - area = " "   asp - controller = " Home"   asp - action = " Index" > Home < / a >< / li > 
131+     < li >< a  asp - area = " "   asp - controller = " Home"   asp - action = " About" > About < / a >< / li > 
132+     < li >< a  asp - area = " "   asp - controller = " Home"   asp - action = " Contact" > Contact < / a >< / li > 
133+     
134+     < secure - content  asp - area = " "   asp - controller = " Role"   asp - action = " Index" > 
135+         < li >< a  asp - area = " "   asp - controller = " Role"   asp - action = " Index" > Role < / a >< / li > 
136+     < / secure - content > 
137+     < secure - content  asp - area = " "   asp - controller = " Access"   asp - action = " Index" > 
138+         < li >< a  asp - area = " "   asp - controller = " Access"   asp - action = " Index" > Access < / a >< / li > 
139+     < / secure - content > 
140+ < / ul > 
141+ ```
142+ 
143+ Don 't forget to add your tag halper namespace to `_ViewImports.cshtml`:  
144+ ```cshtml 
145+ @using  SampleMvcWebApp 
146+ @addTagHelper  * , Microsoft .AspNetCore .Mvc .TagHelpers 
147+ @addTagHelper  * , SampleMvcWebApp 
148+ ```
47149
150+ If  you  extended  `IdentityUser ` or  you  changed  user  and  role  key , you  should  pass  user  and  role  type  too . for  example :
151+ 
152+ ```c #
153+ public  class  ApplicationDbContext  : IdentityDbContext < ApplicationUser >  { .. . }
154+ public  class  MySecureContentTagHelper  : SecureContentTagHelper < ApplicationDbContext , ApplicationUser >  { .. . }
155+ ```
156+ 
157+ or 
158+ 
159+ ```c #
160+ public  class  ApplicationDbContext  : IdentityDbContext < ApplicationUser , ApplicationRole , int >  { .. . }
161+ public  class  MySecureContentTagHelper  : SecureContentTagHelper < ApplicationDbContext , ApplicationUser , ApplicationRole , int >  { .. . }
162+ ```
163+ #
164+ 
165+ If  you  don 't want to use the default UI, follow the below steps to discover controllers and actions and give access to the role and then assign role(s) to the user.  
48166The  next  step  is  discovering  controllers  and  actions . `IMvcControllerDiscovery ` return  all  controllers  and  actions  that  decorated  with  `[Authorize ]` attribute . `IMvcControllerDiscovery .GetControllers ()` method  returns  list  of   `MvcControllerInfo `: 
49167
50168```c #
@@ -73,7 +191,7 @@ public class MvcActionInfo
73191}
74192```
75193
76- The  next  step  is  creating  a  role  assign  acccess  to  it . Use  `RoleManager <>` to  create  role  and  `IRoleAccessStore ` to  store  role  access .
194+ The  next  step  is  creating  a  role  to   assign  access  to  it . Use  `RoleManager <>` to  create  role  and  `IRoleAccessStore ` to  store  role  access .
77195
78196```c #
79197var  role  =  new  IdentityRole  { Name  =  " RoleName"   };
@@ -87,7 +205,8 @@ var roleAccess = new RoleAccess
87205};
88206await  _roleAccessStore .AddRoleAccessAsync (roleAccess );
89207```
90- The  final  step  is  assigning  created  role  to  a  user : 
208+ 
209+ The  final  step  is  assigning  a  created  role  to  a  user : 
91210
92211```c #
93212var  user  =  await  _userManager .FindByIdAsync (" someId"  );
@@ -96,8 +215,7 @@ await _userManager.AddToRolesAsync(user, new [] { "RoleName" });
96215
97216And  now  the  user  only  can  access  those  controllers  and  actions  that  his  roles  can  access .
98217
99- Here  is  an  example  to  create  a  role  and  assign  access  to  the  role . Check  out  samples  to  view  full  implementation .
100- 
218+ Here  is  an  example  to  create  a  role  and  assign  access  to  the  role .
101219```c #
102220public  class  RoleViewModel 
103221{
@@ -176,93 +294,8 @@ public class RoleController : Controller
176294    }
177295}
178296```
179- 
180- You can decorate controllers and actions with ` DisplayName `  attribute to show user a more meaningful name instead of controller and action name.
181- ``` c# 
182- [DisplayName (" Access Management"  )]
183- public  class  AccessController  : Controller 
184- {
185- 
186-     //  GET: Access 
187-      [DisplayName (" Access List"  )]
188-     public  async  Task <ActionResult > Index ()
189- }
190- ```
191- #
192- You can also use default UI to for managing roles and assigning roles to users if you don't want to implement them by yourself.
193- 
194- Install the _DynamicAuthorization.Mvc.Ui_ [NuGet  package ](https:// www.nuget.org/packages/DynamicAuthorization.Mvc.Ui)
195- 
196- ```powershell
197- Install-Package DynamicAuthorization.Mvc.Ui
198- ```
199- 
200- Then `AddUi` to DynamicAuthorization registration:
201- ```
202- services
203-         .AddDynamicAuthorization<ApplicationDbContext>(options => options.DefaultAdminUser =  " UserName"  )
204-         .AddJsonStore (options => options.FilePath =  " FilePath"  )
205-         .AddUi ();
206- ```
207- 
208- Use `/role` url and to manage roles and `/userrole` to assing roles to users.
209- 
210- 
297+ Checkout  samples  to  view  full  implementation .
211298
212299#
213- You can also use a custom `TageHelper` to check whether user has access to view a content or not. create a cutome tag helper that inherits from `SecureContentTagHelper`
214- 
215- ```c#
216- [HtmlTargetElement (" secure-content"  )]
217- public  class  MySecureContentTagHelper  : SecureContentTagHelper <ApplicationDbContext >
218- {
219-     public  MySecureContentTagHelper (
220-         ApplicationDbContext  dbContext ,
221-         DynamicAuthorizationOptions  authorizationOptions ,
222-         IRoleAccessStore  roleAccessStore 
223-         )
224-         : base (dbContext , authorizationOptions , roleAccessStore )
225-     {
226-     }
227- }
228- ```
229300
230- In each view wrap a content or an anchor tag inside `secure-content` tag:
231- 
232- ```html
233- <ul  class = " nav navbar-nav" > 
234-     < li >< a  asp - area = " "   asp - controller = " Home"   asp - action = " Index" > Home < / a >< / li > 
235-     < li >< a  asp - area = " "   asp - controller = " Home"   asp - action = " About" > About < / a >< / li > 
236-     < li >< a  asp - area = " "   asp - controller = " Home"   asp - action = " Contact" > Contact < / a >< / li > 
237-     
238-     < secure - content  asp - area = " "   asp - controller = " Role"   asp - action = " Index" > 
239-         < li >< a  asp - area = " "   asp - controller = " Role"   asp - action = " Index" > Role < / a >< / li > 
240-     < / secure - content > 
241-     < secure - content  asp - area = " "   asp - controller = " Access"   asp - action = " Index" > 
242-         < li >< a  asp - area = " "   asp - controller = " Access"   asp - action = " Index" > Access < / a >< / li > 
243-     < / secure - content > 
244- < / ul > 
245- ```
246- 
247- Don 't forget to add your tag halper namespace to `_ViewImports.cshtml`  
248- ```cshtml 
249- @using  SampleMvcWebApp 
250- @addTagHelper  * , Microsoft .AspNetCore .Mvc .TagHelpers 
251- @addTagHelper  *, SampleMvcWebApp 
252- ```
253- 
254- If  you  extended  `IdentityUser ` or  you  changed  user  and  role  key , you  should  pass  user  and  role  type  too . for  example :
255- 
256- ```c #
257- public  class  ApplicationDbContext  : IdentityDbContext <ApplicationUser > { ... }
258- public  class  MySecureContentTagHelper  : SecureContentTagHelper <ApplicationDbContext , ApplicationUser > { ... }
259- ```
260- 
261- or 
262- 
263- ```c #
264- public  class  ApplicationDbContext  : IdentityDbContext <ApplicationUser , ApplicationRole , int > { ... }
265- public  class  MySecureContentTagHelper  : SecureContentTagHelper <ApplicationDbContext , ApplicationUser , ApplicationRole , int > { ... }
266- ```
267- #
268301To  implement  DynamicAuthorization  step  by  step  by  yourself  checkout  [manual  branch ](https :// github.com/mo-esmp/DynamicRoleBasedAuthorizationNETCore/tree/manual).
0 commit comments