Permission based authorization and performance in CLSA.NET v4

Permission based authorization and performance in CLSA.NET v4

Old forum URL: forums.lhotka.net/forums/t/10603.aspx


nhwilly posted on Tuesday, August 09, 2011

I thought I had a good initial design for doing a permission based authorization model based on Rocky's comments and my understanding of things - until I read in Using CSLA 4 how the principal and hence the identity have to be passed through the dataportal on each call.  That, or they have to be reconstructed on the other end. 

In the latest version of Using CSLA 4, Rocky makes a point of possible performance issues if too much data ends up in the identity.  Uh oh.

Well, the design I have makes it possible to have quite a few permissions - hundreds possibly - in a given application - all stored in a SQL database.  I don't want to reread all that on each dataportal call at the server and if the list is large, I don't want to passed it along the wire on each dataportal call.  I know if there was some easy workaround, Rocky would have suggested it in his writings.  So I guess it's a choice of the lesser of the evils, unless someone has a better idea.

I haven't finalized any of it yet and I thought I'd ask if anyone has used a permission set that's large and which approach they took.  Maybe I'm worried too much about nothing, but I was hoping this security module would work for both my ASP.NET applications and my WPF app.

Thanks in advance.

RockfordLhotka replied on Tuesday, August 09, 2011

This can be a very real concern. I was working with a client last year who wanted extremely granular permissions at a property level. The result was tens of thousands of permissions.

Even if each permission is stored as a bit, the raw data structure was quite huge - too big to pass on each data portal call.

I honestly don't know their resolution, because they continued working after I'd moved on to other things. My suggestions:

  1. Use compression on the bit-wise data structure (most permissions would be 1 for most users, so simple RLE compression would shrink the structure to be very small for almost all users)
  2. Don't pass the principal on each call - instead have the server retrieved a cached copy from the AppFabric cache to handle each call (so the cached identity objects would be available across the app server cluster)

You should be able to predict the likely size of the identity object. And you should be able to predict the load to recreate it from the database for each request. Those two pieces of information should help you decide whether you can afford to pass it on each call, recreate it on each call, or if you need a server-side cache to minimize the security database load.

None of these things are at all unique to CSLA btw. Every web app that has granular permissions has had to deal with this issue for the past 14 years or so. Sadly, there are no really good answers - it depends on your particular situation.

I should also say that most web apps don't have the richness of smart client apps - and this type of challenge is a big reason for that. In my observation, a lot of web apps would like to have this sort of richness, but the developers don't have the time/budget/expertise to make it work - so they back off and go with a far simpler page-based authorization scheme.

nhwilly replied on Tuesday, August 09, 2011

Well, dang.

So a big dictionary of strings is out, huh?

Does this mean I have one enormous structure like this:

Public Enum Permission As Byte
        None = 0
        ManageUsers = 1 << 0
        CreateOrders = 1 << 1
        PurchaseEquipment = 1 << 2
        CancelOrders = 1 << 3
        ...
...
...
CanEditCustomerBirthdateIfIQGreaterThanRoomTemperature = 1 << 49863 End Enum
And then compress it using RLE?
Don't I get into versioning problems like I would with storing serialized data?
Maybe I'll look into AppFabric.  
I didn't know it was free and if it'll get me out of writing low level code, I'm all ears. Big Smile
As always, thanks, Rocky.

RockfordLhotka replied on Tuesday, August 09, 2011

Somewhat like this, yes. There's a new collection type in .NET 4 - something like vector or bitvector or something. If it is serializable it might work.

I had envisioned an array of byte, wrapped in a data structure with methods that made it easy to index into bits in the array - so basically creating a bit[] data type of a sort.

I don't want the code in the individual rules to be complex - so I'd rather create (and thoroughly test) a data structure that exposes a simple and intuitive API for rule authors.

skagen00 replied on Wednesday, August 10, 2011

We use a bit array.

110 permissions is trivial in terms of size.

10,000 permissions maybe getting a little big for my taste for a principal/identity pair.

But most applications - it's hard for me to see a bit array creating an object too heavy to be passed around.

 

nhwilly replied on Thursday, August 11, 2011

Looks like a BitVector32 collection and I believe it serializes just fine.

http://msdn.microsoft.com/en-us/library/system.collections.specialized.bitvector32(v=VS.100).aspx

Thanks, guys.

nhwilly replied on Thursday, August 11, 2011

Also, it seems like the use of the BitVector32 collection is best when there are 32 boolean values only.  So the identity would have a collection of BitVector32 collections.

I'll bet the entire collection of my permissions (in my wildest imagination) could fit in about 400 bytes.  That doesn't seem like too much...

So long as I'm not passing it in for every item in an enormous collection of items, it shouldn't be too bad.

Copyright (c) Marimer LLC