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

Authentication strategy using header parameter #1826

Closed
ericalves opened this issue Oct 8, 2018 · 3 comments
Closed

Authentication strategy using header parameter #1826

ericalves opened this issue Oct 8, 2018 · 3 comments

Comments

@ericalves
Copy link

I'm trying to develop a small API to communicate with mine with LB3.

Now I'm dealing with authentication. I have some doubts. I implemented using the example in @ loopback/authentication.

I am not able to send my authentication hash in the header. How do I get it in the API and validate it in my provider?

One more thing .. I want to create my own strategy, replicating the same rule I use today in LB3 (using bcrypt). How should I proceed? Should I create my own Strategy or dothis at the provider? Do you have any examples of this?

@bajtos
Copy link
Member

bajtos commented Oct 12, 2018

Hello @ericalves, thank you for starting this discussion.

To be honest, authentication and authorization in LB4 is something that we haven't figured out yet, it's on our near term roadmap - see #1839.

I am not able to send my authentication hash in the header. How do I get it in the API and validate it in my provider?

As I understand the design of @loopback/authentication, obtaining the access token (or any other authentication credentials) is the responsibility of the authentication strategy. @loopback/authentication is not providing any strategies out of the box, but aims to be fully compatible with Passport strategies - see http://www.passportjs.org

If you want to send your access token in a request header, then maybe HTTP Bearer is the strategy to use? See http://www.passportjs.org/packages/passport-http-bearer/

One more thing .. I want to create my own strategy, replicating the same rule I use today in LB3 (using bcrypt). How should I proceed? Should I create my own Strategy or dothis at the provider? Do you have any examples of this?

If I understand you correctly, you would like to re-create User and AccessToken models from LB3 and use them to manage the users.

I believe Passport's local strategy is implementing this case, see https://github.com/jaredhanson/passport-local

Notice that the strategy does not make any assumptions about the way how users are stored. The application has to provide a function(username, password, done) callback that checks whether the given username and password exist in the database.

In LB4, such callback can be implemented using UserRepository as follows:

function(username, password, done) {
  userRepo.login(username, password)
    .then(
      user => done(null, user), 
      err => process.nextTick(() => done(err))
    );
}

And the login function can be implemented as follows:

class UserRepository extends DefaultCrudRepository<User, typeof User.prototype.id> {
  // ...

  async function login(username, password): Promise<User> {
    const user = await this.findOne({where: {username}});
    if (!user) return null;
    // compute hash of the supplied password
    const hash = await bcrypt(password, salt, etc.);
    if (user.password !== password) return null;
    return user;
  }
}

I am afraid we don't have any working example yet. I typed the code snippets above from the top of my head, they may not work out of the box.

@bajtos bajtos added the TOB label Oct 12, 2018
@bajtos
Copy link
Member

bajtos commented Oct 15, 2018

One more thing to consider: storing user's password together with user data in the same model (table) opens a lot of security vulnerabilities. For example:

  • When returning user data in HTTP response, the password property must be filtered out.
  • When searching for users, the password must be excluded from the query.
  • It is not possible to do a full replace of user data from a REST client (e.g. "save()") because a) the client usually does not know the password b) password must be changed using a different flow.
  • A policy preventing users from reusing the same password is difficult to implement because old password are not preserved.

For LB4, I would like us to explore the design where passwords are stored in their own table and a relation "user has one password" is configured (#1422 is tracking HasOne relation). We can also use "user has many password" and include a flag (a Password model property) to distinguish between the current active password and the passwords used in the past.

@bajtos
Copy link
Member

bajtos commented Mar 5, 2019

@ericalves good news! We have recently updated https://github.com/strongloop/loopback4-example-shopping to show how to implement authentication using JWT tokens passed via Authorization header.

The example is not using @loopback/authentication yet, we will be making the necessary updates to both the authentication extension and then to the example application in the upcoming weeks.

Where to find authentication-related parts:

I hope this answers you original question. You can subscribe to the following issues to keep track of our progress in moving the relevant bits from the shopping example to the authentication extension:

I am closing this issue as resolved.

@bajtos bajtos closed this as completed Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants