Policy based authentication taking into account what resources an user can work on? - asp.net-core

I have setup my web api to use policy based authorization. I can have permissions like invoice:list, invoice:edit, invoice:delete, order:list, order:edit and so on.
Now, I need to return different sets of data depending on the user that is logged in. For example an user can retrieve all invoices (sales manager for example) and others just the ones created by them.
Would it be a good way to do it, add a bit more information to the claim like -> inovice:list:all, invoice:list:own, etc...? And add differnt filters to the final query depending on the "all" or "own" part?
What other alternatives can be implemented to solve this problem?
Cheers.

Related

Web App: How is administrator access usually done

Currently I'm building a web app. So far I only have regular users. However, due to some requirements I need to have special admin accounts for the app administrators. I'm wondering now how these are usually implemented. The requirement is, that they use the same login mask as regular users and behave the same except for the additional capabilities. To differentiate I could put an admin flag into the users' profile or put the admins into a separate table in my DB. Maybe the the second option scales better for potential additional user groups. Also, how could these admins be signed up? I don't want to use predefined usernames I check against in the login handler. I know the question is rather general. I'm just looking for some directions.
Since you didn't give information about the platform(s) you are using, I can only give theoretical answer. While a simple "isadmin checkbox" will do the job for only separating normal users and admins, but if you will need another user type such as "power users" etc. you will keep adding new columns to your table, which is not ideal. Basically you can use a "Role Based" or a "Permission" based approach. In Role based, as the name implies, you assign each user a role and give access to specific resources depending on the role. In the "Permissions" approach you define for each user the permissions they have (resources to access, actions they can perform). Also you could combine these two approaches, where you assign each user his role and define permissions for each role.

Claims-based auth and circles of users

Let's think of a simple REST-based web service to store and retrieve JSON objects. Without any authentication, every user can access any data.
Now let's add usage of JWTs to authenticate users. Of course, since we are not doing authorization, still every user can access anything, but at least now we know who accesses what.
Next step: When storing an object, save the user's sub claim with the object, and verify that the user's sub claim matches the one of the requested object, and if so, deliver it. Now we have authorization on a per-user basis. So far, so easy.
Now let's add the possibility to let users share objects with other users. For the sake of simplicity, say, we want to have predefined groups (i.e., roles) and we want to let the user choose which group (role) has access to the objects they create. This is still easy, as you have a predefined list of groups, so you can let the user choose one or more, and attach them to the object. Additionally, the identity provider needs to be configured in a way that it put a groups claim into every user's token, so we can match them. As we can already see from the length of this paragraph, things become more complex.
Question 1: Am I right so far, that handling "static" groups this way it the way to go?
Now, let's give the users the opportunity to create groups on their own. This is still not complicated, but how do we make the identity provider use the dynamically created groups? For sure we do not want to make an administrator update the identity provider's configuration every day ;-).
Question 2: How do we handle dynamically created groups?
Now, finally, let's forget about groups, and let's say, that we want to allow the users to be able to simply share their objects with other users. This should be configurable for every object individually. How do we do this? Do we save a list of users on the object? If so, what exactly do we save? The sub claim? If so, how does the owner user know the appropriate values? Or ...?
And: Supposed the users want to put their friends dynamically into dynamically generated circles, how would we do that?
Question 3: How do tokens and dynamically created groups with dynamically assigned users work with each other?
In my opinion the tokens should only include identity-information(-claims) you'll need to identify the user on your ressource server or that wont change when refreshing, since you wouldn't want your user (or your app in place) to have to refresh his access tokens each and every time his permissions change (since access tokens grant access for a specific amount of time you wouldn't want your user to have access to certain ressources that he's lost the access rights to since his last token refresh by not refreshing the token and simply using the old one either). The more security related information you append to your token, the more vulnerability you may add to your system (depending on your token lifetime).
Stating so, I would (and always do) identify the users roles or groups by his user-id (which is included in the jwt-token) on the ressource server. To achieve this, I always attach the users identity-information to the current request on my ressource server and attach "dynamic"-claims like the users role or group to the identity.
By adding only the identity information I need to identify the user and the user's rights on my ressource server, I tend to use my identity providers across multiple applications without handling application scope on the identity provider, so I can use the exact same access token for multiple independent ressource servers.

Using openLDAP groups to authenticate users for different services

I am currently setting up a small server with several applications. Since no Active Directory etc is planned, but I do need a centralized user administration, I decided for LDAP since all applications are capable of authenticating against it.
I have already set up a domain "dc=example,dc=lan". It has two organizational Units. Groups and Users. My plan was, to create a posixGroup for every application, so that a user can be added to each group (if he/she was allowed to use this application).
The structure would then be (example):
for each group
cn=ejabberd,ou=groups,dc=example,dc=lan
where cn=ejabberd is of type "posixGroup"
and for users
cn=user1,ou=users,dc=example,dc=lan
where cn=user1 is of type "posixAccount"
Some, but not all, applications expect the "mail" attribute as login name. Some don't.
My problem is, that searching for users in ou=users is easy as 1,2,3 - searching in "cn=ejabberd,ou=groups,dc=example,dc=lan" is sheer driving me crazy since the users are not a "child" to this group but a "memberuid" attribute.
I have tried different filters and thought about another setup.. Just cannot think of anything different making sense right now.
Am I running down the wrong way, or maybe just blind to what's right in front of me?
I'd be glad for any finger pointing out a direction.
So here is, how I did it:
I created the following structure.
+dc=example,dc=com
+ou=groups
| +employees (PosixGroup)
| +service1 (GroupOfNames)
| +service2 (GroupOfNames)
+ou=users
| +user1 (User Account)
| +user2 (User Account)
etc..
Groups like "service1" and "service2" are of type "GroupOfNames". Furthermore I had to install the "memberOf"-Overlay so I could search for this exact attribute of a user.
This now gives me the possibility to tell each service to use a search filter that returns only the members of one special group, which will be granted access. For instance, ejabberd will use this filter:
"(&(objectClass=inetOrgPerson)(memberof=cn=ejabberd,ou=groups,dc=example,dc=com))"
Found these informations on the following website. Just take care to set the filter case sensitive! "memberOf" will not return any results, since the overlay in this example uses "memberof".
http://www.schenkels.nl/2013/03/how-to-setup-openldap-with-memberof-overlay-ubuntu-12-04/
I suggest you're on the wrong track. You don't want to authenticate by application, you just want to define overall roles that users can be in. The applications can then be defined to require certain role(s) per application funtion, web page, etc. As a limiting case, an application can be a role, but if you set out to define it that way you're overly limiting yourself.
To answer your immediate problem, you only have to search under the ou=Groups item for posixGroups which have memberUID={0} where {0} is the DN of the user. In other words the search filter is
(&(objectClass=posixGroup)(memberUID={0}))
Iterating those search results then gives you the DNs of all the groups of which he is a member.

Can I use Shibboleth to present different attributes of other users to different users

OK, so it's a badly phrased question. But it's hard to explain in a single line.
I've tried to read the Shibboleth documentation and being a newbie got out of my depth fairly rapidly. I don't really want to spend days understanding it if an expert can take half a minute to say "no chance, that won't work".
I have many groups of users, lets say (for now) that groups are different companies.
What I'd like to do is only allow users to see some fields from other companies.
For example I'm Alice in Company A and I can see that Bob in Company B has an email address bob#b.com. He can see that I'm alice#a.com
However everyone else in Company B can see that Bob has a last name and a phone number etc.
And everyone else in Company A can see my details.
To make this more complicated, lets say that Bob and I become friends and decide we want to share our information then we create a "transient" group "alice&bob". Because we are both members of that group, we can both see each others full details. (But nobody else in A can see Bob's details unless they are also friends and vice versa)
I can sort all that out in application code by querying all attributes and relationships and only showing what's relevant but for extra security I'd like to limit the disclosure of information at source.
I think I need to use attribute filters but not sure if they are able to give me this level of control. With this flexibility of being able to form relationships, will I need to build filter files on the fly and then end up with thousands of filters that Shibboleth starts to choke on because the logic is so long.
Something like the "is requester in group" filter rule :
https://wiki.shibboleth.net/confluence/display/SHIB2/IdPFilterRequirementAttributeRequesterInEntityGroup
The answer above is quite good, but i believe that non shibboleth users will find it confusing.
The quick answer is You really don't want to do it this way, it may be possible to do but for 100% there are better tools to do it.
Ok, full version now (sorry for being too obvious i some places).
In shibboleth architecture we can distinguish two main components.
Identity Provider IdP- which holds information about users from specific organizations.
Service Provider SP - which are generally some service or protected resource, for which we can define some access rules
In your example credentials for Alice and Bob could be stored in different IdP, because they are member of different organizations/companies, or (which isn't exactly matching the whole pattern) you can have one IdP for all users, and "company" is just one of user attributes. IdP doesn't provide you any kind of api that will give you opportunity to access users attributes for any user, apart from the one that is being authenticated.
On the other hand you have your SP, which hold some super secret resources, for which you can define policies. And in which you would like to define polices for user information.
And here lays the problem, on SP side you don't have access to whole users database, that's the way Shibboleth works. You can of course treat all users information as a resource in your SP, but why in the hell would you like to use Shibboleth if you have clear access to all users credentials on you application side?
If you store all users information on you service side I believe that any well designed relational database with some kind of authentication for your service will be better than shibboleth for this job.
Hope that helped.
This is not a job for Shibboleth or for most SAML/SSO providers, for that matter. The attribute filtering you speak of is used for filtering those attributes between the IdP and SP ... which is basically saying : let service provider or "application" B see the following attributes from IdP A.
Once you transmit the attributes to the SP on the other end, Shibboleth does not (and indeed cannot) provide you with a mechanism to prevent users of application B from seeing any data that you present to them ... in fact, they really shouldnt be able to see any data transmitted by the IdP unless you are exposing it in someway via your application.

Designing a permissions based security model

I work on a vb.net winforms app where we currently are using simple roles for security. We enable/disable specific controls based on if the current user has the required role. We are to the point where this is no longer granular enough.
Our application is based on different physical locations we call sites. A user might have permission to do something (for example, edit a site's configuration) at one site but not another. Therefore, we now need to lookup permissions based on current user AND current site. Also, a certain user's permissions may be very specific to themselves ie. no other user's permissions are exactly the same as another user's. Therefore we need a security model that's more permissions based rather than role based.
What's the best way to design a new permissions model that can meet these requirements? I want to make sure that it's easy to implement the checking in the code (I don't want a million if statements sprinkled in our SetUIPermissions methods) and we don't want to have to update every user (400+ and counting) each time we add a new permission. Because of this last requirement I think we need to keep the idea of roles but possibly add/remove exceptions for particular permissions for specific users.
Any ideas?
You're on the right track with the roles and permissions. It's a relatively common solution to have a role refer to a set of "default" permissions; by having a user have a role and a set of permissions, you allow for the role to be overridden by the set of permissions specifically granted / revoked for that user. This gives reasonable flexibility and granularity, and supports your situation of adding new permissions (in the role) without needing to touch every user.