8

So, I believe I understand the logic behind authorization standards like OAuth. The OAuth token contains information about the user (name, role, etc.), which I can use to secure my application.

It's about the last part of the previous sentence that I have a question. Let's say I have a web app with 1000 articles, how do I check whether or not a specific user (based on his/her OAuth token) has access to a certain article? I see several options:

  1. I store all ID's of the articles that the user can see in the OAuth token (e.g. ID1, ID2, ID3, etc.);
  2. Conversely, I can also store which users may access the article (e.g. Article 1 can be read by users 1,2,3). This is like an ACL;
  3. For every article, I store which roles can access that article (e.g. Article 1 can be read by role: reader). This is like RBAC;
  4. Do not secure your content at all, just like Facebook seems to do (although they do secure it, but they just check your friend list before giving you the direct url to the resource).

To clarify: I am not searching for an answer that explains that you can put claims in the token itself, so that you do not have to hit the db to retrieve your claims (stateless). I am looking for ways how the application back-end uses these claims to decide whether or not access to a certain content item is granted.


  • Option 1 seems bad practice, as the tokens will become infinitely huge for large providers.
  • If large providers use option 2 or 3, they will have a huge amount of database hits (check if that article can be accessed by that user), which can't be good for performance. This performance increase is one of the reasons Facebooks and Twitters use stateless authorization, instead of stateful authorization. I would assume that this performance penalty on content level is a blocker against using either option 2 or 3.
  • So, is the only viable option to go with 4?

A last option I see is to use option 3, combined with heavy caching. As content permissions are not as ephemeral as user rights, this is the option I would go for. But is this how large providers (Google, Twitter, Dropbox, etc.) do it? And how is it implemented practically?


Update

Someone told me about Spring's permission matrix which you can put in memory, but I'm not sure whether this would be the way to go..

  • Typically 2 or 3 for dynamic content and 4 for static resources. You have to hit some kind of data store to load the content, so checking permissions as well is not a crazy overhead. It's likely to initially hit memcached or redis, backed by an SQL database. – paj28 Oct 18 '15 at 8:17
  • Group/role permissions stored in redis. Can handle many requests per second. – Z.T. Oct 18 '15 at 8:43
  • 1
    Voted to close/move as it's not really on topic. The question is more related to the effective database request handling than security. – Lucas Kauffman Oct 18 '15 at 9:04
  • @LucasKauffman, depending on the answer, you are correct in saying that the question should be moved. However, the permission matrix I linked to is security-specific, and an answer going in that redirection belongs here I believe. On the other hand, in case it is just about caching database requests, the question could be moved. – Michael Oct 18 '15 at 9:17
3
+50

Every article has an associated permissions object attached to it. That permissions object describes the code to be evaluated and any possible parameters. Most contexts are fairly normalized, such as in Facebook where the context might be friends.

Thus, the viewer's control evaluates its attached rules: if you're a friend, it succeeds. That's a pretty fast operation. You can go further, attaching specific data to the control (I share something with all my friends except Eve, or with a specific list). You can also set rules for a viewer: an editor might have a privacy controller attached to their context that returns true for all calls.

There are two good examples off the top of my head that can see some of the workings of. The first is Amazon AWS permissions: policies are attached to both users and objects and they describe permitted actions on AWS. In the case of AWS, the rule starts off with implicitly deny. All rules attached to the user and the service are evaluated, and the boolean logic is if permitted and not explicitly_denied. Check out the IAM policy simulator for a graphical view of how things evaluate.

The other view is PAM services for Unix, which lets you write any code you'd like taking the user into account and marking the result of that as required, sufficient, or a few other options.

For your specific case, every you might setup an evaluation for RBAC, an evaluation for specific

By the way, both Facebook and Twitter use stateful authorization. At least in Facebook's case regarding images, the actual access to a cached image isn't checked to allow remote caching, but it is during page generation. It is a database call every time. A typical page load on Facebook can generate over 100,000 database calls. Simple KV type stores, memcache, and strong parallelism really help make that work.

0

Some suggestions:

You should store the oauth token, you get from the logged in user, somewhere. With each request you can therefore verify this token. This creates a huge number of requests and can slow down your service. What you can do is, implement your own token based on this oauth token which you save in a DB and for example store this token client side in a cookie or session id.

On the back end the token needs to be validated upon each request. As you may have seen google, airbnb and so on just load some basic layout and the rest is loaded with ajax requests which make the whole page seem more quick. So in each request you have to add your current token and of course validate it on the server side.

With this idea in mind you can serve sites which require login really fast as theyre mostly static.

Another idea on access lists. You could also group the user and differentiate these rights by the group the actual user is in.

EDIT: Nowadays I would go definitely for a secured API and mostly standard HTML Pages so that the API can decide what to deliever. This has the advantage of a fast response and you can do all your checks in the background.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.