casbin / Casbin.NET

An authorization library that supports access control models like ACL, RBAC, ABAC in .NET (C#)
https://casbin.org
Apache License 2.0
1.16k stars 111 forks source link

Casbin best practices #239

Open natilivni opened 2 years ago

natilivni commented 2 years ago

Hello,

I want to implement casbin in my .NET application but have a few questions.

Is it best practice for the enforcer to be a singleton or to create a new one each time you need to authorize?

Is there a recommended adapter for Ms sql server?

Is there a recommended adapter for postgres?

As a follow up to #2 and #3, is it best practice for the adapter to be a singleton or to recreate it for each request?

I appreciate any advice on these topics

casbin-bot commented 2 years ago

@sagilio @xcaptain @huazhikui

hsluoyz commented 2 years ago

@sagilio

sagilio commented 2 years ago
  1. EF Core adapter is currently maintained by Casbin community and will be updated most actively.
  2. In Casbin v1.x, because the model is not thread-safe and it is necessary to create a new Enforcer and Model instance when a new HTTP request.
  3. In Casbin v2.x, it is best to use a single SycedModel instance to create Enforcer. (https://github.com/casbin/Casbin.NET/blob/preview/NetCasbin/SyncedEnforcer.cs), this will save time on each load all policies.
Leonardo-Ferreira commented 2 years ago

Suggestion number 2 and 3 seems highly wasteful... I'd advocate that you should pool Enforcers. You can use a middleware to get a instance from the pool and return it at the end

shayura commented 2 years ago

[...] should pool Enforcers. You can use a middleware to get a instance from the pool and return it at the end

Wouldn't it be more space efficient to free memory up right after the enforcement call?

I suppose that using a filtering, database-backed policy adapter one could achieve decent performance by defining database indices over the policy domain or resource, although this doesn't seem to be the case in the current EFCore adapter implementation. Then again, without pooling one might end up with loading multiple overlapping partitions of the same policy, in which case loading the whole policy once would've been better.

What do @sagilio and @hsluoyz think is a memory efficient approach to using Casbin, especially with more sizeable policies consisting of, say, 500k lines or more?

In Casbin v2.x [...]

Out of curiosity, is a stable v2 planned to release any time soon? I'll open a separate ticket in the casbin-aspnetcore repository, because it seems that the v2-preview version isn't compatible with that project.

Leonardo-Ferreira commented 2 years ago

space efficient to free memory up right after the enforcement call?

don't fool yourself, YOU can't free memory. All you can do is signal that an instance can be collected. GC is the one that actually does the heavy lifting of memory management... also, if you're going to load n reload the same Enforcer all the time, why waste CPU instantiating e releasing it? GC is not cheap you know...

shayura commented 2 years ago

YOU can't free memory. All you can do is signal that an instance can be collected.

You're completely right. I took the liberty of ignoring the semantics of memory management for argument's sake and assumed that the garbage collector would eventually do its job. I was already aware that C# is a memory managed language but didn't know it had no reference counting mechanism. Thanks for pointing that out.

After some additional pondering I tend to agree, at least in part, with your sentiment about reloading the Enforcer multiple times. Primarily due to the cost of instantiating all those objects. It's trading time for space efficiency. In that case, pooling the enforcer makes sense.

why waste CPU instantiating e releasing it? GC is not cheap you know...

What I wasn't suggesting is to force garbage collection. I guess I was more concerned with the cost of instantiating objects corresponding to rules that might never be queried during the decision process, and using a filtering adapter to avoid that. Then again, in extreme cases one could still end up loading overlapping partitions of the same policy.

sagilio commented 2 years ago

[...] should pool Enforcers. You can use a middleware to get a instance from the pool and return it at the end

Wouldn't it be more space efficient to free memory up right after the enforcement call?

I suppose that using a filtering, database-backed policy adapter one could achieve decent performance by defining database indices over the policy domain or resource, although this doesn't seem to be the case in the current EFCore adapter implementation. Then again, without pooling one might end up with loading multiple overlapping partitions of the same policy, in which case loading the whole policy once would've been better.

What do @sagilio and @hsluoyz think is a memory efficient approach to using Casbin, especially with more sizeable policies consisting of, say, 500k lines or more?

In Casbin v2.x [...]

Out of curiosity, is a stable v2 planned to release any time soon? I'll open a separate ticket in the casbin-aspnetcore repository, because it seems that the v2-preview version isn't compatible with that project.

@shayura @Leonardo-Ferreira The policy is only cached in the model instance, the allocation of a new enforcer instance is cheap. Singleton the model instance is a memory efficient approach and pooled the model instance is a performance efficient approach. A note that the filtered adapter is read-only.