Skip to content

Authorizer triggers twice #4351

@rajkaran

Description

@rajkaran

I have created a basic authorizer by following offical documentation and loopback4-example-shopping.

I have found that every time I hits api end point, consol.log in cutom authorizer provider triggers twice.

Steps to reproduce

below is my code.

role-based-authorizer.service.ts

import {bind, /* inject, */ BindingScope, Provider} from '@loopback/core';
import { Authorizer, AuthorizationContext, AuthorizationMetadata,
AuthorizationRequest, AuthorizationDecision} from '@loopback/authorization';

@bind({scope: BindingScope.TRANSIENT})
export class RoleBasedAuthorizerProvider implements Provider<Authorizer> {
    constructor(/* Add @inject to inject parameters */) {}

    value(): Authorizer {
        return this.authorize.bind(this);
    }

    async authorize( context: AuthorizationContext,
    metadata: AuthorizationMetadata ) {

        // console.log('RoleBasedAuthorizerProvider context', context)
        console.log('RoleBasedAuthorizerProvider metadata', metadata)
        if (
            context.resource === 'UserController.prototype.findById' &&
            context.principals[0].name === 'user-01'
        ) {
            return AuthorizationDecision.DENY;
        }

        return AuthorizationDecision.ALLOW;
    }
}

end point in user.controller

@get('/users/{id}', {
        security: OPERATION_SECURITY_SPEC,
        responses: {
            '200': {
                description: 'User model instance',
                content: {
                    'application/json': {
                        schema: getModelSchemaRef(User, {
                            includeRelations: true
                        }),
                    },
                },
            },
        },
    })
    @authenticate('jwt')
    @authorize({ resource: 'user', scopes: ['fetch'], allowedRoles: ['admin'], voters: [compareId] })
    async findById(
        @param.path.string('id') id: string,
        @param.query.object('filter', getFilterSchemaFor(User)) filter ? : Filter < User >
    ): Promise < User > {
        let user = await this.userRepository.findById(id, filter);
        delete user.password;
        return user;
    }

registering in application.ts

this.component(AuthorizationComponent);
this.bind('authorizationProviders.rolebased-provider')
            .toProvider(RoleBasedAuthorizerProvider)
            .tag(AuthorizationTags.AUTHORIZER);

Current Behavior

sees console.log printed twice

RoleBasedAuthorizerProvider metadata {
  resource: 'user',
  scopes: [ 'fetch' ],
  allowedRoles: [ 'admin' ],
  voters: [ [AsyncFunction: compareId] ]
}
RoleBasedAuthorizerProvider metadata {
  resource: 'user',
  scopes: [ 'fetch' ],
  allowedRoles: [ 'admin' ],
  voters: [ [AsyncFunction: compareId] ]
}

Expected Behavior

Should be printed only once. I am planning to make a query within authorizer. If I go ahead with current behaviour then I will see two database queries instead of a single one.

Is there a way to prevent this?

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions