1

I am building a web application that involves a login system. Once a user has logged in and is authenticated they should have the ability to access data from a database. This is however where I get a bit confused. How would I go about limiting the users' data to a specific area? For example, if user A requests data from the database about user B, how would you go about implementing a control system that could tell whether you have the right to that data or not?

I'm just speculating, maybe this is not the approach you wish you take.

1
  • You already got the point you need a "control system" which checks before any request or access if an user if authorized to do so. For checking you need to implement a set of rules that define what actions are allowed to what user.
    – Robert
    Nov 11, 2021 at 19:23

2 Answers 2

1

This is an extremely generic question about one of THE major topics in security - authorization, also known as access control - which is quite complicated. Consequently it's not practical to give a proper answer on the basis of the little information you've given so far.

However, I can recommend a few different approaches, with pseudocode implementations. One thing to note is that all of these typically require that the user be identified (authenticated) before they can take any access-controlled actions, although technically this isn't always required (sometimes an authorization authority can grant a user a token that doesn't identify them but does state what access they have).

  • User-based access control. In this model, a user has full access to their own data, and limited (or no) access to anybody else's. (Obviously, this requires tracking who owns each datum or other securable object.) This is a simplistic model but it works pretty well; in practice, almost every site out there uses user-based access control at least some of the time. For example, on this very site, you can directly edit or delete their own posts and profiles and so forth, without most users having any such privileges to your posts or profile. Same on sites like Facebook and Gmail. Typically this solution doesn't fully scale, though, so it's mixed with others. The actual implementation is usually very simple: for each securable object you store who owns it, and the check is authorization = request.user == object.owner ? full : none. Sometimes it's a bit more complicated though, e.g. if a user has granted some specific other users access to their own object too, in which case it might be authorization = request.user == object.owner ? full : request.user in object.allowed_users ? : partial : none
  • Role-based access control. Also abbreviated RBAC, this is one of the most common models when you have a lot more users than distinct levels of access, because it's simple and scales very well. In a nutshell, every user has a "role" (sometimes termed a "group" although in theory that's slightly different) such as "reader" or "author" or "developer" or "admin", which determines what the user can do. Most authorization checks are made against the role rather than against the specific user. Some checks might still be made against the user (e.g. to edit your own profile), but in general this works well. If all objects' access controls are the same, it's just authorization = request.user.role.authorized_actions or if different object types have different access controls for each role then , it's authorization = request.user.role in object.authorized_roles ? object.type.authorized_roles[request.user.role].authorized_actions : none
  • If a user can have multiple distinct roles, that's often termed "groups" instead (you may already be familiar with groups; they're a core part of the security model on Windows, MacOS, and Linux). For example, Alice might be a member of "Moderators" and "Admins", empowered both to lock discussion threads, access moderator-only threads, and edit user accounts; Bob might be a member of "Moderators" and "Backup Users", empowered to lock user threads and access moderator-only threads, and download user content from the site in as a ZIP file. Groups are also often used to grant access to a "team" or similar, for example, I might create a group "cbhacking-housemates" and then share a document to the group rather than to the members individually (which means new members automatically have access and people who leave or are kicked from the group automatically lose access). A simple (but inefficient) way to implement this (with authorization being a bit-field of permission flags) might be authorization = 0; foreach group in request.user.groups { if group in object.allowed_groups { authorization |= object.allowed_groups[group] } } and then if e.g. one group gives you edit (but not download) and another gives you download (but not edit) privilege, you'd have both.

Of course, there's still the question of what you do with this authorization data when you have it. In general, you define - for every single request, usually via something like an annotation on the request handler function - what the required authorization is to carry out the request, and also pass the requesting user and object in question. The annotation then figures out whether the requesting user has the required authorization to carry out the requested action on the target object. In practice you don't usually collect the full list of authorizations and then go see whether it includes the requested action; it's more efficient to look up the specific role(s) or group(s) that are authorized to perform the requested action (in general, or on that object in particular), and just check if the requesting user is a member (or is the owner of the data in question, who can presumably do whatever).

For stuff where the permissions are dynamic - e.g. on Google Docs, where I can create a doc (owner has Full authorization), specify the doc can be edited by my spouse (another user granted Edit authorization), specify that my housemates can Comment on the doc (a group granted Comment authorization), and that anybody with the link can read the doc (everybody else gets Read-only authorization, where normally they wouldn't have any) - the actual implementation can get kind of hairy and generally can't be done as a simple lookup function of the user and the requested endpoint. However, it could still be done as a function of the user, the object (a particular Google Doc in the above example), and the endpoint (e.g. if the user tries to leave a comment). Also, permissions might be hierarchical (Owner > Editor > Commenter > Reader > none) or not (Owner can edit or delete, Moderator can move or lock, Backup Operator can download, Security Analyst can view the detailed audit log; none of these imply the others).

Like I said, it's a major and complicated topic.

0

User Access Control ensures correct data access for authorized users, and prevents unauthorized users to access, however, as you asked, Authorized users also must be controlled, the data can be protected also from unauthorized changes/access by authorized users also.

Its not practical to define access control for all users (if you have many users) you can create Group Based Access Control and add similar users to those Groups based on their access, you can also design the data access based on owners, if the user created that row of data then you can allow access and limited modification, and prevent other to view and modify.

Generally, this can be implemented using MySQL table having some columns to define user (by id), specific data (by id and table), etc.

Its also very important to enable user audit logs for tracking changes and ability to revert back the changes in case of unauthorized access happens.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .