Loopback-next: LB4 - Authorization Implementation - Cannot find name AuthResponse - Authorization sample

Created on 14 May 2019  路  26Comments  路  Source: strongloop/loopback-next

Description / Steps to reproduce / Feature proposal

I followed the Authorization tutorial at https://loopback.io/doc/en/lb4/Loopback-component-authorization.html and i have compilation error in "sequence.ts" at AuthResponse Statement (see below)

const authUser: AuthResponse = await this.authenticateRequest(request);

Cannot find name 'AuthResponse'

NOTE: I followed and completed the Authentication piece and getting token successfully in Authentication flow. Please help where i am doing wrong. I followed the exact article provided.

Please check below code for Sequence.ts

import { inject } from '@loopback/context';
import {
FindRoute,
InvokeMethod,
ParseParams,
Reject,
RequestContext,
RestBindings,
Send,
SequenceHandler,
HttpErrors,
} from '@loopback/rest';
import { AuthenticationBindings, AuthenticateFn } from '@loopback/authentication';

import {
AuthorizatonBindings,
AuthorizeFn,
AuthorizeErrorKeys,
UserPermissionsFn,
PermissionKey
} from './authorization';

const SequenceActions = RestBindings.SequenceActions;

export class MySequence implements SequenceHandler {
constructor(
@inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
@inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
@inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
@inject(SequenceActions.SEND) public send: Send,
@inject(SequenceActions.REJECT) public reject: Reject,
@inject(AuthenticationBindings.AUTH_ACTION)
protected authenticateRequest: AuthenticateFn,
@inject(AuthorizatonBindings.USER_PERMISSIONS)
protected fetchUserPermissons: UserPermissionsFn,
@inject(AuthorizatonBindings.AUTHORIZE_ACTION)
protected checkAuthorization: AuthorizeFn,
) { }

async handle(context: RequestContext) {
try {
const { request, response } = context;
const route = this.findRoute(request);
const args = await this.parseParams(request, route);
// This is the important line added to the default sequence implementation
const authUser: AuthResponse = await this.authenticateRequest(request);

  // Parse and calculate user permissions based on role and user level
  const permissions: PermissionKey[] = this.fetchUserPermissons(
    authUser.permissions,
    authUser.role.permissions,
  );
  // This is main line added to sequence
  // where we are invoking the authorize action function to check for access
  const isAccessAllowed: boolean = await this.checkAuthorization(
    permissions,
  );
  if (!isAccessAllowed) {
    throw new HttpErrors.Forbidden(AuthorizeErrorKeys.NotAllowedAccess);
  }

  const result = await this.invoke(route, args);
  this.send(response, result);
} catch (err) {
  this.reject(context, err);
}

}
}

Current Behavior

Expected Behavior

_See Reporting Issues for more tips on writing good issues_

Authorization

Most helpful comment

Some docs were finally merged into the repo last night, although they still need to be released to loopback.io.

Please take a look at :

https://github.com/strongloop/loopback-next/blob/master/docs/site/Loopback-component-authentication.md

https://github.com/strongloop/loopback-next/blob/master/docs/site/tutorials/authentication/Authentication-Tutorial.md

@loopback/authentication/README.MD still needs to be revised. This is in progress at the moment.

Hope this helps.

All 26 comments

@venkatamandala
Apologies for the broken example, we are in the midst of landing different PRs which
are updating @loopback/authentication .

feat: resolve authentication strategy registered via extension point landed in early May and it was a breaking change.

Draft:Changes to passport strategy adapter will be updating how passport strategies are handled given the new authentication strategy interface. We are exploring a few options right now. Once things have been decided, the documentation you mention will be updated.

refactor shopping cart example to utilize latest @loopback/authentication module is also in the works at the moment.

So please stay tuned...

:)

P.S. Same comment for https://github.com/strongloop/loopback-next/issues/2886 and https://github.com/strongloop/loopback-next/issues/2887.

@venkatamandala AuthResponse is actually the authenticated User Model. Its implementation is not described in the documentation as it can vary application to application. In general, AuthResponse is the returned user model after authentication. You can use the User Model as well, in place of it.

// Do authentication of the user and fetch user permissions below  
const authUser: User | undefined = await this.authenticateRequest(request);

@samarpanB AuthenticateFn from @loopback/authentication return UserProfile or undefined. Since I use custom User model, it will cause an error because it's not assignable. Do you have any suggestion?

@bgleolalahi Whatever you return from @loopback/authentication, you should use that as authUser type. You only need to make sure that it contains permissions.
You can also refer to one of our simplistic loopback-starter project (consider it as boiler plate) we created to showcase samples of authentication and authorization and few other significant integrations. It was created to help and provide guidance to developers.

@bgleolalahi, does @samarpanB answer your question? Is this issue good to close? Thanks.

@bgleolalahi Whatever you return from @loopback/authentication, you should use that as authUser type. You only need to make sure that it contains permissions.
You can also refer to one of our simplistic loopback-starter project (consider it as boiler plate) we created to showcase samples of authentication and authorization and few other significant integrations. It was created to help and provide guidance to developers.

Okay, thank you for helping. @samarpanB

@dhmlau Yes, we can close the issue now. Thanks.

hello i have the same problem.i am using loopback/authentification.help please

@DimitriEmman , please have a look at my replies above for solution. If you still face issues, I would need more information on what error you are getting before I can help with that.

Please note this issue was for Authorization implementation not for authentication. If you are facing issues with authentication, please look for existing issues about authentication (if any) related to your problem and any solutions provided there. Or else, you can also raise a new issue providing more details about it.

Hope this helps. Thanks.

Hi @samarpanB thanks for replying.
this is my sequence

import { UserPermissionsFn } from './authorization/types';
import { Authresponse } from './models/authresponse.model';
import {inject} from '@loopback/context';
import {
FindRoute,
InvokeMethod,
ParseParams,
Reject,
RequestContext,
RestBindings,
Send,
SequenceHandler,
HttpErrors,
} from '@loopback/rest';
import {
AuthenticationBindings,
AUTHENTICATION_STRATEGY_NOT_FOUND,
USER_PROFILE_NOT_FOUND,
AuthenticateFn,
UserProfile
} from '@loopback/authentication';

import {
AuthorizatonBindings,
AuthorizeFn,
AuthorizeErrorKeys,
PermissionKey,
} from './authorization';

const SequenceActions = RestBindings.SequenceActions;

export class MySequence implements SequenceHandler {
constructor(
@inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
@inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
@inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
@inject(SequenceActions.SEND) public send: Send,
@inject(SequenceActions.REJECT) public reject: Reject,
@inject(AuthenticationBindings.AUTH_ACTION)
protected authenticateRequest: AuthenticateFn,
@inject(AuthorizatonBindings.USER_PERMISSIONS)
protected fetchUserPermissons: UserPermissionsFn,
@inject(AuthorizatonBindings.AUTHORIZE_ACTION)
protected checkAuthorization: AuthorizeFn,
) {}

async handle(context: RequestContext) {
try {
const {request, response} = context;
const route = this.findRoute(request);
const args = await this.parseParams(request, route);

  //await this.authenticateRequest(request);

  const authUser :  Authresponse   = await this.authenticateRequest(request);
  // Parse and calculate user permissions based on role and user level

  const permissions: PermissionKey[] = this.fetchUserPermissons(
    authUser.permissions,
    authUser.role.permissions,
  );
  console.log('bonjour');
  const isAccessAllowed: boolean = await this.checkAuthorization(
    permissions,
  );
  if (!isAccessAllowed) {
    throw new HttpErrors.Forbidden(AuthorizeErrorKeys.NotAllowedAccess);
  }

  const result = await this.invoke(route, args);
  this.send(response, result);
} catch (err) {
  if (
    err.code === AUTHENTICATION_STRATEGY_NOT_FOUND ||
    err.code === USER_PROFILE_NOT_FOUND
  ) {
    Object.assign(err, {statusCode: 401 /* Unauthorized */});
  }
  this.reject(context, err);
}

}

}

and i get this error after npm start :
src/sequence.ts:55:13 - error TS2322: Type 'UserProfile | undefined' is not assignable to type 'Authresponse'. Type 'undefined' is not assignable to type 'Authresponse'.

55 const authUser : Authresponse = await this.authenticateRequest(request);

i am not using loopback4-authentication but loopback-authentication

i am not using loopback4-authentication but loopback-authentication

You can compare/copy code from a working example: LB4 Shopping example /w auth

@dougal83 did you integrate the authorization in this example(shopping example)?

@DimitriEmman No, it's an official example /w auth implemented by @emonddr & @jannyHou. I think they have/or are sorting out documentation atm. I've managed to copy the example code into my project /wo error so it's viable. Study the example if the docs are not ready yet.

EDIT: New auth docs currently being merged.

Some docs were finally merged into the repo last night, although they still need to be released to loopback.io.

Please take a look at :

https://github.com/strongloop/loopback-next/blob/master/docs/site/Loopback-component-authentication.md

https://github.com/strongloop/loopback-next/blob/master/docs/site/tutorials/authentication/Authentication-Tutorial.md

@loopback/authentication/README.MD still needs to be revised. This is in progress at the moment.

Hope this helps.

@DimitriEmman , @dougal83 ^^ :)

Okay thank you @dougal83 @emonddr .

@DimitriEmman , @dougal83 ^^
I accidentally used a url with a feature branch. I have updated the links above to point to master branch. :)

@emonddr thanks.what about role and permissions in loopback 4.I follow these steps https://loopback.io/doc/en/lb4/Loopback-component-authorization.html but it doesn't work

@DimitriEmman I think I know the issue you are facing. Can you please replace AuthResponse with UserProfile everywhere? That is what is returned by authenticate method. Also in order to make authorisation work, you need to add permissions to the UserProfile model.
Please have a look at my comment here - https://github.com/strongloop/loopback-next/issues/2896#issuecomment-495528708

Please check it out.

hello @samarpanB thank you for replying.i try to replace authresponse by userprofile and i have again problems.
I think authUser Type is only in lb4-auth .no?To be more clearer , if i do like that AuthenticateFn, i am obliged to import lb4-auth,and me i am using lb-auth.
Thanks and sorry i am so new with these technologies

If you can share your code on github somewhere, I can then debug and help you out. It鈥檚 difficult to figure out otherwise .

Good morning ,
lb4-authentication and authorization
Thank you,

Hello @DimitriEmman ,

I can see lots of issues in your codebase unfortunately.

  1. In sequence.ts, you are using AuthenticateFn from @loopback/authentication package which returns UserProfile, but you are assigning it to Authresponse. This can never map.
const authUser :  Authresponse   = await this.authenticateRequest(request);
  1. You do not have permissions in UserProfile object. So authorization cannot work.
  2. You still have loopback4-authentication package in package.json, which is causing some conflicts. Please remove this.

I think what you need to do is follow the authentication documentation shared by @emonddr carefully first. Try to complete the authentication integration successfully first.
Once that is done, then you should use loopback4-authorization package as you have in your package.json, follow the guide there to integrate it.

Sorry I cannot share fully fixed code in your repo. Running little busy to do that. You can refer to our starter project for such guidance. But remember that project is not using @loopback/authentication. It's using loopback4-authentication.

@samarpanB thanks for the help.i will fix the issues

Closing due to inactivity.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marioestradarosa picture marioestradarosa  路  3Comments

aceraizel picture aceraizel  路  3Comments

shadyanwar picture shadyanwar  路  3Comments

teambitcodeGIT picture teambitcodeGIT  路  3Comments

rexliu0715 picture rexliu0715  路  3Comments