Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(docs): update migration docs for authentication/authorization #4440

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 130 additions & 5 deletions docs/site/migration/auth/built-in.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,133 @@ sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-auth-built-in.html
---

{% include note.html content="
This is a placeholder page, the task of adding content is tracked by the
following GitHub issue:
[loopback-next#3719](https://github.com/strongloop/loopback-next/issues/3719)
" %}
## Migrate the authentication flow

### Request access tokens via login

In LoopBack 3, the built-in `User` model exposes a `login` endpoint at
`POST /Users/login`. It allows a user to be authenticated with `username/email`
and `password`. Successful login returns a JSON object that contains the `id` as
the access token. See
https://loopback.io/doc/en/lb3/Introduction-to-User-model-authentication.html#login-as-the-new-user.

The `login` method can also be used programmatically behind other endpoints. For
example:

```js
router.post('/projects', function(req, res) {
var email = req.body.email;
var password = req.body.password;

app.models.User.login(
{
email: email,
password: password,
},
'user',
function(err, token) {
if (err)
return res.render('index', {
email: email,
password: password,
loginFailed: true,
});

token = token.toJSON();

res.render('projects', {
username: token.user.username,
accessToken: token.id,
});
},
);
});
```

See
https://github.com/strongloop/loopback-example-access-control/blob/master/server/boot/routes.js#L19-L41.

1. Implement the login endpoint in LoopBack 4:

We can add the `login` method to a controller and expose it as `/users/login`
endpoint:

- Login method

- https://github.com/strongloop/loopback4-example-shopping/blob/master/packages/shopping/src/controllers/user.controller.ts#L204

```ts
@post('/users/login', {
responses: {
'200': {
description: 'Token',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
token: {
type: 'string',
},
},
},
},
},
},
},
})
async login(
@requestBody(CredentialsRequestBody) credentials: Credentials,
): Promise<{token: string}> {
// ensure the user exists, and the password is correct
const user = await this.userService.verifyCredentials(credentials);

// convert a User object into a UserProfile object (reduced set of properties)
const userProfile = this.userService.convertToUserProfile(user);

// create a JSON Web Token based on the user profile
const token = await this.jwtService.generateToken(userProfile);

return {token};
}
```

Optionally, we can provide `UserService` and `TokenService` to verify
credentials and generate access tokens.

- User service

- https://github.com/strongloop/loopback4-example-shopping/blob/master/packages/shopping/src/services/user-service.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please provide an example code showing how to implement a typical User service using the artifacts migrated from a LB3 application? The guide does not explain how to "reuse the User database from LB3", I think it's important to include those instructions here.


- Token service

- https://github.com/strongloop/loopback4-example-shopping/blob/master/packages/shopping/src/services/jwt-service.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Can you please provide an example code showing how to implement a typical Token service using the artifacts migrated from a LB3 application? The guide does not explain how to reuse the AccessToken model from LB3, I think it's important to include those instructions here.


2. Reuse the `User` database from LB3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if "reuse" is the right choice here. The User models work very differently in LB3 and LB4.


- Datasource for the User database
- UserCredentialsRepository

- https://github.com/strongloop/loopback4-example-shopping/blob/master/packages/shopping/src/repositories/user-credentials.repository.ts

### Mark a method that requires authentication

- @authenticate

### Protect API calls with access tokens

- JWT strategy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, LoopBack 3 applications are typically not using JWT strategy, because we don't have first class support for that.

Maybe it's possible to set up JWT auth strategy in a LB3 app using loopback-component-passport? That's out of scope of this part of the migration guide, where we should focus on the built-in auth & auth as provided by LB3 core.


- https://github.com/strongloop/loopback4-example-shopping/blob/master/packages/shopping/src/authentication-strategies/jwt-strategy.ts

## Migrate the authorization flow
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please explain how to map acls entries from model JSON files to LB4 @authorize calls and show some example code.

Please explain this in more details and provide an example code showing how to implement a typical Authorizer service using the artifacts migrated from a LB3 application. Also explain how to migrate Role and RoleMapping entries that are stored in a database.

What are other sources of authorization rules in LB3 that users may need to migrate to LB4?


### Migrate ACLs

1. Decorate protected methods with `@authorize`

- https://github.com/strongloop/loopback4-example-shopping/blob/11c48ef222a7960cb266bd88878c0eb9f8138127/packages/shopping/src/controllers/user-order.controller.ts#L48

2. Implement an Authorizer

- https://github.com/strongloop/loopback4-example-shopping/blob/master/packages/shopping/src/services/authorizor.ts
36 changes: 36 additions & 0 deletions docs/site/migration/auth/example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
lang: en
title:
'Migrating authentication and authorization for an example LoopBack 3
application'
keywords: LoopBack 4.0, LoopBack 4, LoopBack 3, Migration
sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-auth-example.html
---

## Example LoopBack 3 application

- https://github.com/strongloop/loopback-example-access-control

## Migration to LoopBack 4

1. Set up `/login` endpoint

2. Set up authentication

- Authentication action
- `@authenticate`
- Authentication strategies

3. Set up authorization

- Migrate ACLs -> `@authorize`
- Migrate custom role resolvers -> `Authorizer` or `Voter`

## Use a third party library as the authorizer

- Casbin

## Use a third party service as the authorizer

- Auth0
122 changes: 109 additions & 13 deletions docs/site/migration/auth/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,119 @@ sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-auth-overview.html
---

## LoopBack 3 authentication and authorization facilities

LoopBack version 3 provides several options for adding authentication and
authorization to secure the applications:
authorization to secure the applications. See
[docs](https://loopback.io/doc/en/lb3/Authentication-authorization-and-permissions.html)
for more details.

### Authentication

1. Built-in `User` and `AccessToken` based authentication
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Should we consider build a component with equivalent User model and AccessToken model?
  • (In the follow-up doc story) We can explain the concept difference between LB3 AccessToken and LB4 token
    • LB3
      • a built-in model, belongsTo a User model
      • it carries the logged in user(or principal? not sure which is more accurate)'s scope, has util apis to return info from request
    • LB4
      • it just refers to the token included in a request's header
      • the access token mentioned in our tutorials work with a particular strategy to perform the authentication
      • developer has the flexibility and responsibility to define the encoded info


LoopBack 3 includes a built-in `User` model with `login` and other methods to
perform username/password based authentication and return an access token, which
can then be used to access protected resources.

2. Integration with [Passport](http://www.passportjs.org/)

[loopback-component-passport](https://github.com/strongloop/loopback-component-passport)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest doing a separate spike for migrating the passport based strategies in the 2nd phase after we figured out the migration guide for the main module.

provides integration between LoopBack 3 and
[Passport](http://www.passportjs.org) to support third-party login and account
linking for LoopBack applications. The migration path is described in
[Migrating Passport-based authentication](./passport.md).

3. oAuth 2.0

[loopback-component-oauth2](https://github.com/strongloop/loopback-component-oauth2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as loopback-component-passport

provides full integration between OAuth 2.0 and LoopBack. It enables LoopBack
applications to function as an oAuth 2.0 provider to authenticate and authorize
client applications and/or resource owners (i.e. users) to access protected API
endpoints. The migration path is described in
[Migrating OAuth2 provider](./oauth2.md).

### Authorization

- A set of built-in models like `User`, `AccessToken` and `ACL` makes it easy to
store your user credentials locally and define custom access control checks.
The migration path is described in
[Migrating built-in authentication and authorization](./built-in.md).

- [loopback-component-passport](https://github.com/strongloop/loopback-component-passport)
provides integration between LoopBack 3 and
[Passport](http://www.passportjs.org) to support third-party login and account
linking for LoopBack applications. The migration path is described in
[Migrating Passport-based authentication](./passport.md).

- [loopback-component-oauth2](https://github.com/strongloop/loopback-component-oauth2)
provides full integration between OAuth 2.0 and LoopBack. It enables LoopBack
applications to function as an oAuth 2.0 provider to authenticate and
authorize client applications and/or resource owners (i.e. users) to access
protected API endpoints. The migration path is described in
[Migrating OAuth2 provider](./oauth2.md).
- Built-in ACL based authorization

## LoopBack 4 authentication and authorization facilities

LoopBack 4 focuses on capturing the minimum common metadata for authentication
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an overview, I am thinking of make a brief comparison of the concept mapping and general process in 3 and 4

Concept Mapping:

  • Authentication (retrieve principal from request)
    • LB3
      • built-in User model: provides persistence for user info, login, logout, and other apis
      • built-in AccessToken model: contains logged in user's auth metadata
      • built-in authentication system that integrates User, AccessToken and other authorization related models(Role, RoleMapping, ACL) to perform the authentication+authorization as a whole
    • LB4
      • create User model to describe data shape, create repository for persistence
      • create User controller for login, logout, other apis
      • implement token service for encoding/decoding principal's info
  • Authorization (determine the principal's access)
    • LB3(I am not very familiar with the lb3 auth, more details TBD)
      • Role
      • RoleMapping
      • ACL
    • LB4

General Process:

  • LB3(see doc)
    • implement authentication
    • specify user roles
    • define access for each role and model method
    • set-up access control for users
  • LB4
    • Authentication
      • create User model, controller(login/logout methods) leveraging User and Token service(we provide interface, developer implements them)
      • decorate endpoints with @authenticate() to specify authentication metadata
      • implements authentication strategies
      • mount authentication component and register strategies
    • Authorization
      • design the implementation of Role, see comment
      • design the implementation of ACL
      • decorate endpoints with @authorize() to specify authorization metadata
      • create authorizers
      • mount authorization component and register authorizers
    • @loopback/security provides types/interfaces to define the contract of auth related concepts

and authorization and enabling extensibility so that different security
strategies/schemes can be plugged in to enforce authentication and
authorization.

### Authentication

In LoopBack 4, `authentication` is enforced as an action of the `Sequence` for
REST.

- AuthenticationStrategy
- PassportAdapter

Please note no built-in username/password based authentication is shipped with
LoopBack 4.

### Authorization

In LoopBack 4, `authorization` is made possible as an interceptor in front of
controller methods or proxied repository/service methods.

- Authorizer/Voter
- Use your own interceptor for authorization

Please note no built-in ACL based authorization is shipped with LoopBack 4.

## Concept mapping

- Authentication (retrieve principal from request)
- LB3
- built-in User model: provides persistence for user info, login, logout,
and other apis
- built-in AccessToken model: contains logged in user's auth metadata
- built-in authentication system that integrates User, AccessToken and other
authorization related models(Role, RoleMapping, ACL) to perform the
authentication+authorization as a whole
- LB4
- create User model to describe data shape, create repository for
persistence
- create User controller for login, logout, other apis
- implement token service for encoding/decoding principal's info
- Authorization (determine the principal's access)
- LB3(I am not very familiar with the lb3 auth, more details TBD)
- Role
- RoleMapping
- ACL
- LB4

## General flow

- LB3(see
[doc](https://loopback.io/doc/en/lb3/Authentication-authorization-and-permissions.html#general-process))
- implement authentication
- specify user roles
- define access for each role and model method
- set-up access control for users
- LB4
- Authentication
- create User model, controller(login/logout methods) leveraging User and
Token service(we provide interface, developer implements them)
- decorate endpoints with `@authenticate()` to specify authentication
metadata
- implements authentication strategies
- mount authentication component and register strategies
- Authorization
- design the implementation of Role, see
[comment](https://github.com/strongloop/loopback-next/issues/4291#issuecomment-572278133)
- design the implementation of ACL
- decorate endpoints with `@authorize()` to specify authorization metadata
- create authorizers
- mount authorization component and register authorizers
- @loopback/security provides types/interfaces to define the contract of auth
related concepts
8 changes: 3 additions & 5 deletions docs/site/migration/auth/passport.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-auth-passport.html
---

{% include note.html content="
This is a placeholder page, the task of adding content is tracked by the
following GitHub issue:
[loopback-next#3958](https://github.com/strongloop/loopback-next/issues/3958)
" %}
## Migrate from `loopback-component-passport`

https://github.com/strongloop/loopback-next/tree/master/extensions/authentication-passport
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid the README for the package at the end of your link does not provide enough information to make it clear for LB3 users what changes they need to make to their applications.