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

LB4 - Authorization Implementation - Cannot find name AuthResponse - Authorization sample #2896

Closed
venkatamandala opened this issue May 14, 2019 · 26 comments

Comments

@venkatamandala
Copy link

venkatamandala commented May 14, 2019

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

@emonddr
Copy link
Contributor

emonddr commented May 15, 2019

@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 #2886 and #2887.

@raymondfeng
Copy link
Contributor

See #1205

@samarpanB
Copy link
Contributor

@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.

@leotj
Copy link

leotj commented May 23, 2019

// 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?

@samarpanB
Copy link
Contributor

@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.

@dhmlau
Copy link
Member

dhmlau commented May 29, 2019

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

@leotj
Copy link

leotj commented May 29, 2019

@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.

@DimitriEmman
Copy link

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

@samarpanB
Copy link
Contributor

@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.

@DimitriEmman
Copy link

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);

@DimitriEmman
Copy link

i am not using loopback4-authentication but loopback-authentication

@dougal83
Copy link
Contributor

i am not using loopback4-authentication but loopback-authentication

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

@DimitriEmman
Copy link

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

@dougal83
Copy link
Contributor

dougal83 commented Jun 13, 2019

@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.

@emonddr
Copy link
Contributor

emonddr commented Jun 13, 2019

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.

@emonddr
Copy link
Contributor

emonddr commented Jun 13, 2019

@DimitriEmman , @dougal83 ^^ :)

@DimitriEmman
Copy link

Okay thank you @dougal83 @emonddr .

@emonddr
Copy link
Contributor

emonddr commented Jun 13, 2019

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

@DimitriEmman
Copy link

@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

@samarpanB
Copy link
Contributor

@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 - #2896 (comment)

Please check it out.

@DimitriEmman
Copy link

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

@samarpanB
Copy link
Contributor

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

@DimitriEmman
Copy link

DimitriEmman commented Jun 14, 2019

Good morning ,
lb4-authentication and authorization
Thank you,

@samarpanB
Copy link
Contributor

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.

@DimitriEmman
Copy link

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

@dhmlau
Copy link
Member

dhmlau commented Mar 28, 2020

Closing due to inactivity.

@dhmlau dhmlau closed this as completed Mar 28, 2020
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

8 participants