What is the recommended way of retrieving a list of all Resources that a User has access to?
In many examples I've seen, Authorization is placed into a separate service -- often one that exposes a method similar to isAuthorized(), which can be used for individual queries ("Is the User authorized to use Resource ABC?") as well as bulk queries ("Is the User authorized to use any of the following list of resources?").
While the authorization-logic exists in the Authorization Service, the enforcement of the authorization policies is kept within the application itself (e.g., business-logic layer for actually implementing access to the resource, based on the result from the Authorization service; or the presentation layer to show/hide individual options based on the result from the Authorization Service, etc.).
What is the preferred way of doing this if, for example, my Data Access layer has potentially billions of "resources" that it could return? Does my business-logic layer query all that data (passing all of it over the network), and then forward that giant list on to the Authorization Service (again over the network), only to get a giant list of "ALLOW/DENY" sent back to the business logic? Obviously that doesn't sound quite right.
Is this a case where we can't have a "clean" separation of data-access, authorization-logic, and business-logic? Should I instead ask my Data-Access layer to only return to me a list of all Resources that the User has access to, which could end up being implemented as a simple database join, but would then require that some of the logic for determining who has access to what resources under what conditions (i.e., the authorization policies) be embedded in the data-access code, and therefore those policies would be spread through-out my code base (e.g., some authorization logic would be in my Data-Access Layer, some would be in my Authorization Layer, etc.)?
Maybe performance trumps a "clean" architecture, but is there a better way of doing this?
Authentication is better to be externalized. Authorization often is too application dependent to externalize. It may work for little systems. But for big systems you will encounter scaling problems as you already expect.
Another thing is returning huge datasets. It seems to me, that this is better placed in reporting. So separate first process modules from reporting modules, that have different requirements because in a business process you need focussed data and in reporting mass data and abstraction.
Authorization is NOT a layer. It's an aspect. An application may not work without a layer if you do not replace it at least with a proper mock. But if you remove aspects you should not have a problem to run the application. Maybe your program will not log anything or you will be able to see more data than you are allowed to see but it will still work.
So should Authorization be externalized from the application domain? No. Should it be separated from the business logic? Yes. The proper mechanism: Aspects (AspectJ, Proxy-Pattern, Template-Class-Pattern). This is my general suggestion.
My special suggestion for "huge data" in business processes is: Try to partition your domain model properly to have little focussed data (Subject "Usability" or "User experience"). Then return to my general suggestion.
If you have to deal with huge amount of data in business processes: Use the last point of "Make It Work Make It Right Make It Fast". Think about it as an optimization for special data requests, that are or are expected to be slow. In this case use special sql queries, pre-loading, caching etc. The DAO-Layer may be the proper location, an caching aspect or an optimization aspect for the DAO-Layer that overrides "working slow"-implementations with alternative implementations that are fast.
The suggestions I made refer to normal business use cases. I am not talking about big data or reporting. As I mentioned these sectors have different requirements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With