Define parameterized policy in OpenAM - openam

We're looking into using OpenAM to handle security for a web app that we've created. I'm wondering about the/a proper way to set up policies that can be parameterized by value. Specifically, we sell items by county. Each user purchases either a few counties or all counties. I know that we could create a role/group/realm for every county in the US, and assign users to the appropriate roles/groups/realms. But that's a lot of things to manage when we'll never have a user buy more than five. Is there a way I can define a rule or policy to say "allow if the resource's county is in the user's list of counties"?
It seems like this should be possible. But I've been looking through OpenAM documentation, and I can't see a place where it says how to do such a thing.

This should be possible by implementing a custom Policy Condition. In your condition you could check the accessed URL (the policy evaluation mode needs to be self though) and you should have also access to the user's session ID, which should allow you to determine if the given user has the necessary privileges to access the given resource.
The documentation is a little bit sparse about this, but should help in general:
http://openam.forgerock.org/openam-documentation/openam-doc-source/doc/dev-guide/index.html#chap-policy-spi

Related

CMS restriction in ASM spartacus

Am working on spartacus, I have a CMSLinkComponent which is having restrictions with user group, lets take admingroup, when i try to impersonate the user who is having admingroup, am unable to see the CMSLinkComponent. I heard that this is an limitation in the spartacus(https://sap.github.io/spartacus-docs/asm/)
Is there any other way to achieve this in spartacus.
As you correctly point out, it is not possible for the AS Agent to apply the customer restriction rules for CMS when impersonating a customer.
The CMS will react according to the authenticated user. In the case of ASM impersonation, the user is the Assisted Service Agent.
As a workaround, perhaps you can evaluate if it is worth giving the AS Agent some additional groups if it makes sense for your use case (and if it even works as intended with the CMS). But there are downsides to this. During customer impersonation, the CMS will always behave according to the CS Agent's groups, regardless or which customer is impersonated.

Keycloak Authorization - best practice roles vs groups

I have a web-application secured with Keycloak. To keep the description of the service short, we have Users and Documents as entities in the service. The users may have access to none or more documents and may edit or read the document.
Currently we have roles such as Admin, EndUser, Developer etc. We then keep a database table outside of Keycloak that maps the documents to users and what user has what access level to what document. All our end-users have the EndUser role in Keycloak. Every single time an EndUser tries to read/edit a Document, we have to make a lookup in the database table for authorization.
We would like to migrate that table to Keycloak. As I understand it I basically have two options:
Create a lot of roles, two for each document with names such as doc_read_[DOCUMENT-ID] and doc_edit_[DOCUMENT-ID] and so on. Then assign the correct role to the correct user. The downside here is that the number of roles will grow A LOT. Also, the number of roles attached to a user will be very large.
Create a group for each document, with the name of the document id. Have different sub-groups for read/write and then add the users in the correct groups. The downside is that the number of groups will be very large. Also, I will rely Authorization on group names, so the list of group names has to be mapped to the token.
I do not want to add a user-attribute with the document-ids to each user. With this approach I can not get an overview of a document and see what users have access to a given Document.
What is the best practice here? Are there any other solutions to solve this issue? This must be a very common setup.
This is just my opinion.
From what I understand both solutions are suboptimal, adding a role per document is unnatural and too finer grain. And as you already mention this would lead to too many roles that probably you will have to add them into the token.
I would personally use Keycloak just for the authentication part and do the authorization part in the backend. I would also try to group the documents in a way that reflect which user roles are allowed to manipulate them.
Alternatively you might try to use Keycloak's Authorization features to handle that use-case, however I have never used it, so there is not much that I can say about this option.
In my opinion what you want to achieve is something that is very tied to your business logic, I wouldn't recomend depending on keycloak to do it. Your token would constantly grow and management would be a nightmare really.
I see no problem in having a service with good cache to lookup permissions, the bulk of the data won't change much over time.

Can I rate-limit requests to Parse.com on a per-user basis?

I'm developing an app using Parse.com for BaaS. Aside from regular security checks, it's my understanding/philosophy that part of security is to assume someone HAS broken in, and then limit the amount they can access/delete/mess up.
One way I'd like to do this is to have a per-user rate limit on certain API requests. I can imagine a sort of naive method where I keep a list of who has accessed recently and when, and check that list before allowing a request of that type to go through (I'm thinking beforeSave for various custom classes).
Is there a better, ideally built-in way?
Though Parse.com doesn't have options for configuring this, parse claims that they keep track of suspicious activities and attempt for DDoS attacks are monitored. But not sure to what extend this is possible, because this specific problem is scenario wise relevant/irrelevant.
You dont have an option to do user level rate limit, but they will report any suspicious activities found like redundant hits from same device.
As given in the Parse docs here, They support two levels of permissions, Class level (via Data browser) & Object level (using ACLs)
Configuring class-level permissions
Parse lets you specify what operations are allowed per class. This
lets you restrict the ways in which clients can access or modify your
classes. To change these settings, go to the Data Browser, select a
class, open the "More" dropdown, and click the "Set permissions" item.
Class level permissions is a manual way of giving access to specific users or roles on a class.
In your case, you might probably need object level permissions based on Access Control Lists(ACL).
Access Control Lists
The idea behind an ACL is that each object has a list of users and roles along with what permissions that user or
role has. A user needs read permissions (or must belong to a role that
has read permissions) in order to retrieve an object's data, and a
user needs write permissions (or must belong to a role that has write
permissions) in order to update or delete that object
Create a new role and add list of users to that role who can access. Then set an ACL like this on the other objects.
{ "role:YourRoleName":{"read":true, "write" : true}}
You can now dynamically add or remove users in that role without updating individual objects.

Azure ACS and storing information for users on it vs local?

I'm working with Azure ACS and incorporating it into an SSO strategy for my .NET 4.0 website. I see on the Rule Groups page that a bunch of different claims can be stored and passed back to the RP (e.g. country, streetaddress, phone, etc.). It looks like you can also return back any claim type you want to create. This got me thinking about many questions relating to storing information for users:
Does it make sense to store user information (other than the nameidentifier) in ACS vs local database tables?
It sounded like you could make unlimited rule groups and rules inside of them. Is that correct?
I would be dealing with different companies and users inside the company. Would creating a rule group for each company and then making rules for each user be a wise choice?
It appears that the API is pretty robust and would enable this to be done automatically as a result of a sign up page, etc. Correct or incorrect?
Would it be feasible and recommended to run a query against ACS to return information back about a user (e.g. query for their email address when they're offline to send them a message about something)
Could you grab bulk information for reporting purposes off of ACS?
The short answer is generally "yes", but of course there's a longer answer :-).
Does it make sense to store user information (other than the nameidentifier) in ACS vs local database tables?
Yes it could make sense. But for optimization purposes you might keep a copy of some of the user profile information somewhere else (local to the app). ACS rules information would be the "master record" you would update the values in your local store whenever you get a token and check whether there've been changes or not.
It sounded like you could make unlimited rule groups and rules inside of them. Is that correct?
No, "unlimited" is a big number. There are limits in the number of namespaces, relying parties and rules. Check the documentation. ACS also supports "cascading" transformations, which can help you reduce the number of rules.
For example:
email: eugeniop#mail.com -> company:Contoso
Company: Contoso -> Language: English
The 2nd rule will be triggered whenever a claim of type "Company", value "Contoso" is issued.
Then you can have:
email: rob#othermail.com -> company: Contoso
The "language" claim will be automatically added.
I would be dealing with different companies and users inside the company. Would creating a rule group for each company and then making rules for each user be a wise choice?
In a multi-tenant environment, it might be better to have a Relying Party per tenant. This is what we do in sample 7 (Federation With Multiple Partners) available here: http://claimsid.codeplex.com
It appears that the API is pretty robust and would enable this to be done automatically as a result of a sign up page, etc. Correct or incorrect?
Yes
Would it be feasible and recommended to run a query against ACS to return information back about a user (e.g. query for their email address when they're offline to send them a message about something)
It is possible. However, there's no concept of "user" in ACS. So yuou would have to decode that from the rules. You can't have a call like "GetUserprofile( string user)"
Could you grab bulk information for reporting purposes off of ACS?
The API supports bulk info, but for reporting it might be better to have replicated information on your own database.
One last thought: ACS rules engine today is very simple and only does simple transformations (plus cascading), but nothing compared to what ADFS can do today, where rules can be really complex (e.g. db lookups, etc)

How can I enforce security or permissions on a bound dataset?

Using a strongly typed dataset and its related table Adapters, normally when I want the changes to pass back, just pass it the table and let it do all the work.
What are some easy ways to enforce security roles on the application user as to which fields they can insert/update/delete when the database is using an application ID instead of user level security?
Do I have to go row by row and check each row against what this particular user is allowed to do (by checking the current version of every field against it's proposed version against their role's permissions?
I believe the first level of security would be locking down the columns on the UI a particular user is not supposed to modify, but what about at the data level? Is there a nice way to do this?
Is this easier in linq-to-sql?
First, are you asking about actual security or just control/saftey/fool-proofing (ie stopping users from doing something dumb)?
If you are trying to enforce security try to answer some questions like who is allowed to connect to the database? where is the actual enforcement (eg, application vs connection to the database)?
For example if your application is where enforcement is placed then what if your application is compromised? Can it then connect to the database and do whatever?
For role separation I would suggest different application that are running/assigned different roles. Each role has to authenticate against the database in some way and only have access to necessary data.
In summary, ask who is doing what to whom and what if they were compromised.

Resources