UNPKG

@loopback/authorization

Version:

A LoopBack component for authorization support.

168 lines (121 loc) 4.05 kB
# @loopback/authorization A LoopBack 4 component for authorization support (Role based, Permission based, Vote based) To read on key building blocks read through [loopback authorization docs](https://loopback.io/doc/en/lb4/Loopback-component-authorization.html) ![Authorization](imgs/authorization.png) ## Installation ```shell npm install --save @loopback/authorization ``` ## Basic use The following example shows the basic use of `@authorize` decorator, authorizer and authorization component by authorizing a client according to its role: ASSUMING your app uses jwt as the authentication strategy, and the user information is encoded in the token from a request's header. ### Define Role Property First **define `role` as a property in your User model** so that after a user logs in, the client's requests will contain that user's role. ```ts @model() export class User extends Entity { @property({ type: 'string', id: true, }) id: string; @property({ type: 'string', id: true, }) role: string; ``` ### Decorate Controller Method Then **decorating your controller methods with `@authorize`** to require the request to be authorized. ```ts import {authorize} from '@loopback/authorization'; import {get} from '@loopback/rest'; export class MyController { // user with ADMIN role can see the number of views @authorize({allowedRoles: ['ADMIN']}) @get('/number-of-views') numOfViews(): number { return 100; } } ``` ### Create Authorizer Provider Next **create an authorizer provider** that compares the request sender's role and the visited endpoint's allowed roles, and returns decision ALLOW if they match. ```ts export class MyAuthorizationProvider implements Provider<Authorizer> { constructor() {} /** * @returns authenticateFn */ value(): Authorizer { return this.authorize.bind(this); } async authorize( authorizationCtx: AuthorizationContext, metadata: AuthorizationMetadata, ) { const clientRole = authorizationCtx.principals[0].role; const allowedRoles = metadata.allowedRoles; return allowedRoles.includes(clientRole) ? AuthorizationDecision.ALLOW : AuthorizationDecision.DENY; } } ``` Finally, **bind the authorizer and mount the authorization component** to your application. The authorization component can be configured with options: ```ts const options: AuthorizationOptions = { precedence: AuthorizationDecisions.DENY, defaultDecision: AuthorizationDecisions.DENY, }; const binding = app.component(AuthorizationComponent); app.configure(binding.key).to(options); app .bind('authorizationProviders.my-authorizer-provider') .toProvider(MyAuthorizationProvider) .tag(AuthorizationTags.AUTHORIZER); ``` After setting up the authorization system, you can create a user with role `ADMIN`, login and get the token, then visit endpoint `GET /number-of-views` with the generated token in the request header. ### Summary and Diagram Here is a summary of the use case and diagram for the example: Endpoint: GET /number-of-views Controller method: ```ts @authenticate(‘jwt’) @authorize({allowedRoles: ['ADMIN']}) @get('/number-of-views') numOfViews(): number { return 100; } ``` Use case: ![Use case](imgs/use-case.png) Authorization artifacts' responsibilities: ![Authorization artifacts' responsibilities](imgs/responsibilities.png) ## Extract common layer `@loopback/authentication` and `@loopback/authorization` share the client information from the request. Therefore we have created another module, `@loopback/security` with types/interfaces that describe the client, like `principles`, `userProfile`, etc. ## Related resources ## Contributions - [Guidelines](https://github.com/loopbackio/loopback-next/blob/master/docs/CONTRIBUTING.md) - [Join the team](https://github.com/loopbackio/loopback-next/issues/110) ## Tests run `npm test` from the root folder. ## Contributors See [all contributors](https://github.com/loopbackio/loopback-next/graphs/contributors). ## License MIT