Package Exports
- @loopback/authorization
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@loopback/authorization) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@loopback/authorization
A LoopBack 4 component for authorization support.
Overview
Authorization decides if a subject can perform specific action on an object.

Role based
Permission based
Vote based
Key building blocks
- Decorate a method to describe:
Permission (maps the method to an action on the protected resource)
- Type of the protected resource (such as
customerororder) - What action does the method represent (such as
changeEmail,createOrder, orcancelOrder)
- Type of the protected resource (such as
ACL (provides role based rules)
- allowedRoles
- deniedRoles
Voters (supplies a list of function to vote on the decision)
- Intercept a method invocation
Build authorization context
- Subject (who) - from authentication
- Map principals to roles
- Inspect the target method for metadata - Permission, ACL, voters
Run through voters/enforcers to make decisions
Decision matrix
The final decision is controlled by voting results from authorizers and options for the authorization component.
The following table illustrates the decision matrix with 3 voters and corresponding options.
| Vote #1 | Vote # 2 | Vote #3 | Options | Final Decision |
|---|---|---|---|---|
| Deny | Deny | Deny | any | Deny |
| Allow | Allow | Allow | any | Allow |
| Abstain | Allow | Abstain | any | Allow |
| Abstain | Deny | Abstain | any | Deny |
| Deny | Allow | Abstain | {precedence: Deny} | Deny |
| Deny | Allow | Abstain | {precedence: Allow} | Allow |
| Allow | Abstain | Deny | {precedence: Deny} | Deny |
| Allow | Abstain | Deny | {precedence: Allow} | Allow |
| Abstain | Abstain | Abstain | {defaultDecision: Deny} | Deny |
| Abstain | Abstain | Abstain | {defaultDecision: Allow} | Allow |
The options is described as follows:
export interface AuthorizationOptions {
/**
* Default decision if all authorizers vote for ABSTAIN
*/
defaultDecision?: AuthorizationDecision.DENY | AuthorizationDecision.ALLOW;
/**
* Controls if Allow/Deny vote takes precedence and override other votes
*/
precedence?: AuthorizationDecision.DENY | AuthorizationDecision.ALLOW;
}The authorization component can be configured with options:
const options: AuthorizationOptions = {
precedence: AuthorizationDecisions.DENY;
defaultDecision: AuthorizationDecisions.DENY;
}
const binding = app.component(AuthorizationComponent);
app.configure(binding.key).to(options);Installation
npm install --save @loopback/authorizationBasic use
Start by decorating your controller methods with @authorize to require the
request to be authorized.
In this example, we make the user profile available via dependency injection
using a key available from @loopback/authorization package.
import {inject} from '@loopback/context';
import {authorize} from '@loopback/authorization';
import {get} from '@loopback/rest';
export class MyController {
@authorize({allow: ['ADMIN']})
@get('/number-of-views')
numOfViews(): number {
return 100;
}
}Extract common layer(TBD)
@loopback/authentication and @loopback/authorization shares the client
information from the request. Therefore we need another module with
types/interfaces that describe the client, like principles, userProfile,
etc... A draft PR is created for this module: see branch
https://github.com/strongloop/loopback-next/tree/security/packages/security
Since the common module is still in progress, as the first release of
@loopback/authorization, we have two choices to inject a user in the
interceptor:
@loopback/authorizationrequires@loopback/authenticationas a dependency. The interceptor injects the current user usingAuthenticationBindings.CURRENT_USER. Then we remove this dependency in the common layer PR, two auth modules will depend on@loopback/security.- This is what's been done in my refactor PR,
PrincipleandUserProfileare still decoupled, I added a convertor function to turn a user profile into a principle.
- This is what's been done in my refactor PR,
The interceptor injects the user using another key not related to
@loopback/authentication.(Which means the code that injects the user stays as it is in https://github.com/strongloop/loopback-next/pull/1205). Then we unify the user set and injection in the common layer PR: same as the 1st choice, two auth modules will depend on@loopback/security.
Related resources
Contributions
Tests
run npm test from the root folder.
Contributors
See all contributors.
License
MIT