1

the last days I was wondering how is it done? How can you authenticate/authorize that the user is allowed to request the data via AJAX.

For now I am using SESSIONS for auth.But this is only a minor protection.

Let´s say I have some function called addUserToGroup($user_id,$group_id), which is called via

EXAMPLE: www.mysite.com/addUserToGroup/1/2  ( user_id = 1 , group_id = 2 )

How can I check if this user is really allowed to join group_id=2? Everyone could just POST data to my server...

One solution I found is using jcryption (public/private key method). But I think,there must be an easier way to somehow check if user_id = 1 is allowed to join group_id = 2.

Thanks in advance!

neubert
  • 15,947
  • 24
  • 120
  • 212
zer02
  • 3,963
  • 4
  • 31
  • 66

3 Answers3

2

Add an extra field to your table users: is_allowed_to_join_2 int(1)

When the person logs in, set

$_SESSION['is_allowed_to_join_2'] = $user['is_allowed_to_join_2'] == 1 ? true : false;

And on the ajax call, in your php code:

if( $_SESSION['is_allowed_to_join_2'] !== true )
{
  exit("Not allowed");
}
Green Black
  • 5,037
  • 1
  • 17
  • 29
  • This will totally work, and provides a poor man's RBAC for a specific entity and operation. However, you should be warned that, if you proceed down this path, you'll be eating a PHP-spaghetti dinner before very long. – Benjamin Cox Aug 17 '12 at 21:31
  • The return variable would probably be in JSON, since the JS logic may want to get a true/false as well - but otherwise, +1. – halfer Aug 17 '12 at 21:31
  • OK, I see. This means I would have to set permission on every single action he could take and write it into my session user_data. But that would be really much. But is this really best practice? :) – zer02 Aug 17 '12 at 21:36
  • It is just meant as example, not as complete solution to the problem, just to show how it could be done. As there is no code provided this would be the simplest way to solve this puzzle. From here you can build a build a nice class with all your roles, add a table for user roles and assign the roles to your users. – Green Black Aug 17 '12 at 21:38
1

How can you authenticate/authorize that the user is allowed to request the data via AJAX.

The same way you auth/authz any other HTTP request.

or now I am using SESSIONS for auth.

Sessions are a sensible way to track if a user is logged in, and who they are logged in as.

How can I check if this user is really allowed to join group_id=2?

The session data tells you who the user is.

On top of that you implement your business logic to determine if they are allowed to join group 2. We can't tell you what that is because we don't know what the business logic is.

If, for example, only users in region 2 countries were allowed to join group 2 then your logic might be something like:

IF session exists
AND user is logged in
AND user's country is in region 2
THEN authorized

Determining if the user's country was in region 2 might be done with some SQL like

SELECT user_id FROM members, countries WHERE user=:username AND members.country=countries.id AND countries.region=:region
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Thanks, but I see no possiblity to check in my businesslogic, if the parameters given are true. – zer02 Aug 17 '12 at 21:38
  • 1
    @zer02 — You don't care if they are "true" (well, you probably do, but that is [a different problem](http://en.wikipedia.org/wiki/Cross-site_request_forgery) which is [easily solved](http://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention)), you care if they are *allowed*. If you don't have rules for what is allowed then either nothing is allowed (delete the script), everything is allowed (forget about security, you don't need it) or you need to decide what the rules are. – Quentin Aug 17 '12 at 21:42
  • Yes I have read some results on google about CRSF before posting this question. Most people were talking about tokens and I found jcryption. Has anyone tried it yet? http://www.jcryption.org/ – zer02 Aug 17 '12 at 21:52
  • @zer02 — Utterly pointless. Use SSL if you care about protecting data in transit (which you should). (That is largely irrelevant to both CSRF and to authz though) – Quentin Aug 17 '12 at 21:54
  • I am not familiar with the effects on the server performance using SSL extensively. For payments etc. I would use SSL. Trade-off security vs performance? – zer02 Aug 17 '12 at 22:03
  • Security without SSL [is a joke](http://en.wikipedia.org/wiki/Firesheep). Processing power is cheap in 2012. – Quentin Aug 17 '12 at 22:05
1

I believe your question is about authorization, not authentication. If I'm right, then presumably you already know who the user is (authentication, perhaps using a cookie or something).

Now, you have to come up with a way of determining what they are allowed to do (authorization).

Authorization logic is really a key design decision. As such, it's non-trivial and depends heavily on the shape of your data model and architecture of your application.

If you can consistently determine whether this should be allowed by applying rules to the data, such as in Quentin's response above (where living in Region 2 is enough to make it such that the User may join Group 2), then it's usually simplest to put this logic in your entity model. In that case, I'd either create a method on User to check whether they can join the group...

function canJoinGroup($group) {
    //if(all is well), then:
    return true
} 

Or create a method to join them which throws an error if disallowed:

function joinGroup($group) {
    //if(all is well), then:
    return true;
    //otherwise:
    throw new Exception("User ". $this->id ." cannot join group " . $group->id);
} 

You could also add a function to Group which delegates to this new User function:

function addUser($user) {
    $user->joinGroup($this);
}

OTOH, If the decisions about who can do what are based on more granular permissions, or based on information an administrator or user needs to be able to change at runtime, then you will have to get a lot fancier. A commonly-used, versatile, and flexible approach is called Role-Based Access Control (aka RBAC).

This can get extremely sophisticated, but the core concept, applied to your case, is that you have a User, and Entity (the Group) and an Operation (join). You need to determine whether User 1 is allowed to do the Operation called 'join' with Group 2 as an argument.

In order to do this, you will have to keep a set of rules somewhere, and then do two things:

  1. keep these tables up-to-date when new Users and Groups are added to the system, or when an Administrator changes their permissions
  2. check these tables with each request to see if the User can perform the Operation on the Entity (check whether the User can Join the Group)

I won't get into the low-level details of this use case. Suffice it to say that, if what you're trying to accomplish today will eventually need to grow into a fairly sophisticated permissions system, you'd do well to study up on RBAC.

Benjamin Cox
  • 6,090
  • 21
  • 19
  • Thank you very much. Yes, I have to think about the database design and the rules. That is really a lot! :) – zer02 Aug 17 '12 at 21:58
  • 1
    You're most welcome! Sorry if I scared you... but it's better to find out how complicated things could get up front, rather than by getting stuck having to refactor a half-baked solution once you're under deadline pressure. – Benjamin Cox Aug 17 '12 at 22:11