Skip to content

Commit 9dd0514

Browse files
committed
create security/authorization component
1 parent c5cd96b commit 9dd0514

File tree

7 files changed

+380
-2
lines changed

7 files changed

+380
-2
lines changed

src/app/security/authorization/authorization.component.css

Whitespace-only changes.
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
<div class="container pt-3">
2+
<div class="row">
3+
<div id="sidebar" style="width: 260px;">
4+
<app-sidebar></app-sidebar>
5+
</div>
6+
<div id="content" class="flex-grow-1" style="width: 400px;">
7+
<article>
8+
<h1>Authorization</h1>
9+
<hr>
10+
<p>
11+
Authorization is the process that determines if the user has permission to access or use resources, and usually is coupled with authentication so that the server has some concept of who the user is before determining what the user can do.
12+
</p>
13+
<p>
14+
The authorization is controlled by the <code>Authorize</code> filter which is responsible for enforcing the authorization policy on the endpoint action. It uses the <code>Authorization</code> service to evaluate the policy and decide which rule applies to the action. The rule can allow or deny access to the action based on various criteria.
15+
</p>
16+
<h3>Configuration</h3>
17+
<p>
18+
To use the authorization feature in your application, you need first to add the <code>Authorization</code> service to the dependency, which also depends on the <code>Authentication</code> service, and the code below shows a simple way to add this feature.
19+
</p>
20+
<pre><code class="language-php">&lt;?php
21+
22+
namespace Application;
23+
24+
use DevNet\System\TimeSpan;
25+
use DevNet\Web\Hosting\WebHost;
26+
use DevNet\Web\Extensions\ApplicationBuilderExtensions;
27+
use DevNet\Web\Extensions\ServiceCollectionExtensions;
28+
29+
class Program
30+
&lcub;
31+
public static function main(array $args = [])
32+
&lcub;
33+
$builder = WebHost::createDefaultBuilder($args);
34+
$builder->register(function ($services) &lcub;
35+
// The authentication service is needed for authorization service.
36+
$services->addAuthentication(function ($builder) &lcub;
37+
$builder->addCookie();
38+
});
39+
// Adding the authorization service
40+
$services->addAuthorization();
41+
});
42+
...
43+
}
44+
}</code></pre>
45+
<br>
46+
<h3>Simple Authorization</h3>
47+
<p>
48+
By default, applying the <code>Authorize</code> filter on the endpoint action without specifying any option will restrict the execution of that action only for authenticated users, as shown in the code example below.
49+
</p>
50+
<pre><code class="language-php">&lt;?php
51+
52+
use DevNet\Web\Action\Filters\Authorize;
53+
use DevNet\Web\Http\HttpContext;
54+
...
55+
56+
$app->useEndpoint(function($routes) &lcub;
57+
$routes->mapGet("/account", function(HttpContext $context) &lcub;
58+
$user = $context->User;
59+
$claim = $user->findClaim(fn ($claim) => $claim->Type == "name");
60+
$name = $claim ? $claim->Value : null;
61+
return $context->Respose->writeAsync("Welcom &lcub;$name}");
62+
})
63+
// Adding the authorize filter.
64+
->addFilter(new Authorize());
65+
});</code></pre>
66+
<p>
67+
You can also apply the <code>Authorize</code> filter to a controller's action methods using the attribute syntax.
68+
</p>
69+
<pre><code class="language-php">&lt;?php
70+
71+
namespace Application\Controllers;
72+
73+
use DevNet\Web\Action\ActionController;
74+
use DevNet\Web\Action\Filters\Authorize;
75+
use DevNet\Web\Action\IActionResult;
76+
77+
class AccountController extends ActionController
78+
&lcub;
79+
#[Authorize]
80+
public function index(): IActionResult
81+
&lcub;
82+
$user = $this->Context->User;
83+
$claim = $user->findClaim(fn ($claim) => $claim->Type == "name");
84+
$name = $claim ? $claim->Value : null;
85+
return $this->content("Welcom &lcub;$name}");
86+
}
87+
88+
public function register(Registration $form): IActionResult
89+
&lcub;
90+
$data = [];
91+
if (file_exists(__DIR__ . '/../../data.json')) &lcub;
92+
$json = file_get_contents(__DIR__ . '/../../data.json');
93+
$data = json_decode($json);
94+
}
95+
96+
$user = new User();
97+
$user->Username = $form->Username;
98+
$user->Password = $form->Password;
99+
$user->Role = "User";
100+
101+
$data[] = $user;
102+
$json = json_encode($data, JSON_PRETTY_PRINT);
103+
file_put_contents(__DIR__ . '/../../data.json', $json);
104+
105+
return $this->content("The user was successfully created.");
106+
}
107+
}</code></pre>
108+
<p>
109+
Another way to restrict access to the controller's action method is to use the Authorize attribute on the entire controller class, which applies the Authorize filter to all the action methods in the controller. But, If you want to exclude some action methods from that, you can use the <code>Authorize("Anonymous")</code> attribute on those methods to override the class-level filter that requires the user to be authenticated and allow access to anyone.
110+
</p>
111+
<p>
112+
In this example, the Authorize filter is applied to all controller methods except for the <code>register()</code> and <code>login()</code> methods.
113+
</p>
114+
<pre><code class="language-php">&lt;?php
115+
116+
namespace Application\Controllers;
117+
118+
use DevNet\Web\Action\ActionController;
119+
use DevNet\Web\Action\Filters\Authorize;
120+
use DevNet\Web\Action\IActionResult;
121+
use Application\Models\Configuration;
122+
use Application\Models\Login;
123+
use Application\Models\Registration;
124+
125+
#[Authorize]
126+
class AccountController extends ActionController
127+
&lcub;
128+
public function index(): IActionResult
129+
&lcub;
130+
// code.
131+
}
132+
133+
#[Authorize('Anonymous')]
134+
public function register(Registration $form): IActionResult
135+
&lcub;
136+
// code.
137+
}
138+
139+
public function settings(Configuration $form): IActionResult
140+
&lcub;
141+
// code.
142+
}
143+
144+
#[Authorize('Anonymous')]
145+
public function login(login $form): IActionResult
146+
&lcub;
147+
// code.
148+
}
149+
}</code></pre>
150+
<br>
151+
<h4>Authorization with a specific scheme</h4>
152+
<p>
153+
When your application uses multiple authentication methods, such as cookie-base and token-base authentications, you may need to control how your application grants access to its resources based on the authentication scheme, and you can do this by specifying the authentication scheme in the Authorize filter to select which authentication method should be used to authorize access to particular resources.
154+
</p>
155+
<p>
156+
This example code authorizes only cookie-based authentication.
157+
</p>
158+
<pre><code class="language-php">&lt;?php
159+
160+
namespace Application\Controllers;
161+
162+
use DevNet\Web\Action\ActionController;
163+
use DevNet\Web\Action\Filters\Authorize;
164+
use DevNet\Web\Action\IActionResult;
165+
use DevNet\Web\Security\Authentication\AuthenticationScheme;
166+
167+
#[Authorize(AuthenticationScheme::CookieSession)]
168+
class AccountController extends ActionController
169+
&lcub;
170+
public function index(): IActionResult
171+
&lcub;
172+
// code.
173+
}
174+
}</code></pre>
175+
<p>
176+
And the following example code authorizes only token-based authentication.
177+
</p>
178+
<pre><code class="language-php">&lt;?php
179+
180+
namespace Application\Controllers;
181+
182+
use DevNet\Web\Action\ActionController;
183+
use DevNet\Web\Action\Filters\Authorize;
184+
use DevNet\Web\Action\IActionResult;
185+
use DevNet\Web\Security\Authentication\AuthenticationScheme;
186+
187+
#[Authorize(AuthenticationScheme::JwtBearer)]
188+
class AccountController extends ActionController
189+
&lcub;
190+
public function index(): IActionResult
191+
&lcub;
192+
// code.
193+
}
194+
}</code></pre>
195+
<br>
196+
<h3>Role-based Authorization</h3>
197+
<p>
198+
Role-based authorization is a method of regulating access to resources based on the roles of users within a system. It specifies roles that the current user must have as claims in order to access the requested resource.
199+
</p>
200+
<p>
201+
For example, in the code below, only users with the role of Administrator can access the resources, in other words only users that have the claim "Role" with the value "Administrator" are accepted.
202+
</p>
203+
<pre><code class="language-php">&lt;?php
204+
205+
namespace Application\Controllers;
206+
207+
use DevNet\Web\Action\ActionController;
208+
use DevNet\Web\Action\Filters\Authorize;
209+
use DevNet\Web\Action\IActionResult;
210+
211+
class AccountController extends ActionController
212+
&lcub;
213+
#[Authorize(roles: ['Administrator'])]
214+
public function index(): IActionResult
215+
&lcub;
216+
return $this->content("Hello Administrator");
217+
}
218+
}</code></pre>
219+
<br>
220+
<h4>Authorization with multiple roles</h4>
221+
<p>
222+
Multiple roles can be specified as an array of strings using the named argument <code>roles:</code> in the Authorize attribute, and the user must have at least one of these roles to access the resources.
223+
</p>
224+
<pre><code class="language-php">&lt;?php
225+
226+
namespace Application\Controllers;
227+
228+
use DevNet\Web\Action\ActionController;
229+
use DevNet\Web\Action\Filters\Authorize;
230+
use DevNet\Web\Action\IActionResult;
231+
232+
class AccountController extends ActionController
233+
&lcub;
234+
#[Authorize(roles: ['Administrator, Manager'])]
235+
public function index(): IActionResult
236+
&lcub;
237+
return $this->content("Hello to either Administrator or Manager");
238+
}
239+
}</code></pre>
240+
<p>
241+
When applying multiple Authorize attributes, the associated resources can only be accessed if the user satisfies all specified roles, unlike the previous example, where the user only needs to have at least one of the roles.
242+
</p>
243+
<pre><code class="language-php">&lt;?php
244+
245+
namespace Application\Controllers;
246+
247+
use DevNet\Web\Action\ActionController;
248+
use DevNet\Web\Action\Filters\Authorize;
249+
use DevNet\Web\Action\IActionResult;
250+
251+
class AccountController extends ActionController
252+
&lcub;
253+
#[Authorize(roles: ['Administrator'])]
254+
#[Authorize(roles: ['Manager'])]
255+
public function index(): IActionResult
256+
&lcub;
257+
return $this->content("Hello to Administrator and Manager");
258+
}
259+
}</code></pre>
260+
<br>
261+
<h3>Policy-based Authorization</h3>
262+
<p>
263+
Policy-based authorization is a way of creating authorization rules that depend on claims requirements that the user must satisfy to access a resource. It can require any user's claims such as ID, Name, Email, Role, etc., unlike role-based authorization, which is just a special case of policy-based authorization that only requires the role claim.
264+
</p>
265+
<p>
266+
To use a policy in your application, you must first define it in the Authorization service by calling the addPolicy() method, which allows you to specify a group of claim requirements, as shown in the following example.
267+
</p>
268+
<pre><code class="language-php">&lt;?php
269+
270+
namespace Application;
271+
272+
use DevNet\System\TimeSpan;
273+
use DevNet\Web\Hosting\WebHost;
274+
use DevNet\Web\Extensions\ApplicationBuilderExtensions;
275+
use DevNet\Web\Extensions\ServiceCollectionExtensions;
276+
277+
class Program
278+
&lcub;
279+
public static function main(array $args = [])
280+
&lcub;
281+
$builder = WebHost::createDefaultBuilder($args);
282+
$builder->register(function ($services) &lcub;
283+
$services->addAuthentication(function ($builder) &lcub;
284+
$builder->addCookie();
285+
});
286+
// Adding the authorisation service with policy
287+
$services->addAuthorisation(function($config) &lcub;
288+
$config->addPolicy("Administration", function ($policy) &lcub;
289+
$policy->RequireClaim('EmployeeNumber');
290+
$policy->RequireClaim('Role', ['Administrator', 'Manager']);
291+
}
292+
});
293+
});
294+
...
295+
}
296+
}
297+
</code></pre>
298+
<p>
299+
And here is an example of how to apply a policy in the Authorize attribute using the named argument <code>policy:</code>
300+
</p>
301+
<pre><code class="language-php">&lt;?php
302+
303+
namespace Application\Controllers;
304+
305+
use DevNet\Web\Action\ActionController;
306+
use DevNet\Web\Action\Filters\Authorize;
307+
use DevNet\Web\Action\IActionResult;
308+
309+
class AccountController extends ActionController
310+
&lcub;
311+
#[Authorize(policy: 'Administration')]
312+
public function index(): IActionResult
313+
&lcub;
314+
return $this->content("Administration space");
315+
}
316+
}</code></pre>
317+
</article>
318+
<nav class="no-print" aria-label="Page navigation">
319+
<ul class="nav-page">
320+
<li class="nav-page-item">
321+
<a class="nav-page-link" routerLink="/docs/security/authentication">
322+
<i class="chevron left"></i> Previous
323+
</a>
324+
</li>
325+
<li class="nav-page-item">
326+
<a class="nav-page-link" routerLink="/docs/security/identity">
327+
Next <i class="chevron right"></i>
328+
</a>
329+
</li>
330+
</ul>
331+
</nav>
332+
</div>
333+
</div>
334+
</div>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { AuthorizationComponent } from './authorization.component';
4+
5+
describe('AuthorizationComponent', () => {
6+
let component: AuthorizationComponent;
7+
let fixture: ComponentFixture<AuthorizationComponent>;
8+
9+
beforeEach(async () => {
10+
await TestBed.configureTestingModule({
11+
declarations: [ AuthorizationComponent ]
12+
})
13+
.compileComponents();
14+
15+
fixture = TestBed.createComponent(AuthorizationComponent);
16+
component = fixture.componentInstance;
17+
fixture.detectChanges();
18+
});
19+
20+
it('should create', () => {
21+
expect(component).toBeTruthy();
22+
});
23+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import hljs from 'highlight.js/lib/common';
3+
4+
@Component({
5+
selector: 'security-authorization',
6+
templateUrl: './authorization.component.html',
7+
styleUrls: ['./authorization.component.css']
8+
})
9+
export class AuthorizationComponent implements OnInit {
10+
11+
constructor() { }
12+
13+
ngOnInit(): void {
14+
hljs.highlightAll();
15+
}
16+
17+
}

src/app/security/security-routing.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import { NgModule } from '@angular/core';
22
import { RouterModule, Routes } from '@angular/router';
33
import { OverviewComponent } from './overview/overview.component';
44
import { AuthenticationComponent } from './authentication/authentication.component';
5+
import { AuthorizationComponent } from './authorization/authorization.component';
56

67
const routes: Routes = [
78
{ path: 'docs/security/overview', component: OverviewComponent },
89
{ path: 'docs/security/authentication', component: AuthenticationComponent },
10+
{ path: 'docs/security/authorization', component: AuthorizationComponent },
911
{ path: 'docs/security', redirectTo: 'docs/security/overview', pathMatch: 'full' }
1012
];
1113

0 commit comments

Comments
 (0)