casbin / node-casbin

An authorization library that supports access control models like ACL, RBAC, ABAC in Node.js and Browser
https://casbin.org
Apache License 2.0
2.6k stars 218 forks source link

[Question]How to add RBAC with domains in loopback4 #412

Open PoyuLU opened 1 year ago

PoyuLU commented 1 year ago
export class CasbinAuthorizationProvider implements Provider {
constructor(
@Inject('casbin.enforcer.factory')
private enforcerFactory: (name: string) => Promise<casbin.Enforcer>,
) {}

/**

@returns authenticateFn
*/
value(): Authorizer {
return this.authorize.bind(this);
}
async authorize(
authorizationCtx: AuthorizationContext,
metadata: AuthorizationMetadata,
): Promise {
const subject = this.getUserId(authorizationCtx.principals[0].id);
const resourceId = await authorizationCtx.invocationContext.get(
RESOURCE_ID,
{optional: true},
);
const object = resourceId ?? metadata.resource ?? authorizationCtx.resource;
const request: AuthorizationRequest = {
subject,
object,
action: metadata.scopes?.[0] ?? DEFAULT_SCOPE,
};

const allowedRoles = metadata.allowedRoles;

if (!allowedRoles) return AuthorizationDecision.ALLOW;
if (allowedRoles.length < 1) return AuthorizationDecision.DENY;

let allow = false;

// An optimization for ONLY searching among the allowed roles' policies
for (const role of allowedRoles) {
  const enforcer = await this.enforcerFactory(role);

  const allowedByRole = await enforcer.enforce(
    request.subject,
    request.object,
    request.action,
  );

  debug(`authorizer role: ${role}, result: ${allowedByRole}`);
  if (allowedByRole) {
    allow = true;
    break;
  }
}

debug('final result: ', allow);

if (allow) return AuthorizationDecision.ALLOW;
else if (allow === false) return AuthorizationDecision.DENY;
return AuthorizationDecision.ABSTAIN;
}

how to add domain in casbin.authorizer?

casbin-bot commented 1 year ago

@nodece @Zxilly @Shivansh-yadav13

PoyuLU commented 1 year ago

@nodece @Zxilly @Shivansh-yadav13

Hi, anyone can give me some tips how to modified domain in node.casbin, thank you.

Zxilly commented 1 year ago

Looks like you implement role management without casbin?

 const allowedRoles = metadata.allowedRoles;

 if (!allowedRoles) return AuthorizationDecision.ALLOW;
 if (allowedRoles.length < 1) return AuthorizationDecision.DENY;
PoyuLU commented 1 year ago

Looks like you implement role management without casbin?

 const allowedRoles = metadata.allowedRoles;

 if (!allowedRoles) return AuthorizationDecision.ALLOW;
 if (allowedRoles.length < 1) return AuthorizationDecision.DENY;

And you create enforcer everytime

const enforcer = await this.enforcerFactory(role);

Seems not a good practice, if you use rbac in casbin, it has to rebuild the whole role graph every time.

I have casbin in different file. How to access the domain value and compare with RBAC with domain model in the above code?

[request_definition] r = sub, dom, obj, act

[policy_definition] p = sub, dom, obj, act

[roledefinition] g = , ,

[policy_effect] e = some(where (p.eft == allow))

[matchers] m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act

Zxilly commented 1 year ago

I think you use this file and want to add domain support? https://github.com/loopbackio/loopback-next/blob/master/examples/access-control-migration/src/components/casbin-authorization/services/casbin.authorizer.ts

Please ref to https://github.com/casbin/node-casbin/blob/master/test/rbacwDomainAPI.test.ts

PoyuLU commented 1 year ago

I think you use this file and want to add domain support? https://github.com/loopbackio/loopback-next/blob/master/examples/access-control-migration/src/components/casbin-authorization/services/casbin.authorizer.ts

Please ref to https://github.com/casbin/node-casbin/blob/master/test/rbacwDomainAPI.test.ts

What if I have thousands of users, how do I check their roles and domains dynamically?