Implement authorization in SOA - soa

I have a question abut what is the best practice/pattern to ensure proper authorization in my SOA application. I have a bunch of services that allow users access certain data (stored in DB). An example of a typical scenario is...
We have a EMPLOYEE table that has say a one to many relationship with PROJECT. So AN EMPLOYEE can have many PROJECTS. Also each employee belongs to a region. The users of the system are allowed to edit information on employee and projects. However Each user only manages data for a few regions and therefore can only modify employees and their projects that belong to a region that the user manages. So user may have access to regions A, B, C and can edit employee/project data for Region A employee but not region Z employee.
I have one service that lets you edit an employee and another to edit an project. Similarly a project has relationships to other entities, for e.g. SCHEDULE, and I have services to edit those as well.
However my problem is this -- whether an user can edit or not a project or schedule, by calling the corresponding service, is determined by which region the employee (to which these projects and schedules are related) belongs to. So for every service to modify a project or schedule or any entity in that hierarchy of data starting at employee, I am having to query the corresponding employee and enforce the region constraints. Which can become very expensive operation considering the database calls and number of joins (my real example has lot of such entities and corresponding services) I have to make on every service call. Is there a more elegant light weight solution for my scenario?

First of all, I'd call these requirements regular business rules rather than authorization. Authorization is usually much more generic in nature, meaning whether a user is allowed access to a specific system or is allowed to invoke a certain function (regardless of parameters).
Second, and based on a business rules view, you should take into account the consistency needs around these business rules before dividing things up into services.
Third, relating to your statement "my real example has lot of such entities and corresponding services", it usually not a good idea to have services that correspond to entities.
So, in summary, you need to redesign your service boundaries such that the rules that need to be enforced (in a highly consistent manner) are contained within a single service. One way to do that is to take different parts of a given entity and put them in different services - provided that there aren't any business rules that demand consistency across those diffe

Related

Oracle APEX User Rights and Previleges

I do not have much experience and I would like to know if there is an easy way to create user rights and privileges, so that each user can access only specific records from the database tables, based on the level he belongs to.
More specifically, suppose we have a group of companies where this group has some companies and these companies have some branches and the branches have some users.
I want the user belonging to the "group of companies" level to have access to and view all the entries in the database related to that group and what is below it (its companies and the branches of these companies).
The user who belongs to the "company" level should have access and see only the files of this company and the branches that this company may have in the database.
The user belonging to the "Branch" level should only be able to access and view this barnch records in the database.
And finally the user belonging to the "End User" level to have access and see only the records created by the user in the database.
Of course level "administrator" will have access to all records in the database.
I thought of creating a user table with a field "User_Level" and in each table to enter USER_ID where based on this I can find the level of a user but how can I restrict access based on the Group of Companies or the Company or the Branch where it belongs?
In APEX you can create authorization schemes to determine what components a user has access to within an application - but that is just a part of the answer to this question. Your question is about filtering the data that is showed to a user based on certain criteria.
There are a couple of possible solutions to this. Since this is a very broad question I'm just going to give you pointers/concepts to start your research. Up to you to determine what solution/combination is most suitable for your implementation.
Concept: Multi-Tenancy
If the data is used by multiple tenants then add a tenant_id to each table that has tenant specific data. In your case a tenant should be a branch. A simple design could be a groups table (to hold branch - companies - company groups), a group_members table (to define relationship between branch - companies - company groups OR between any group and a user) and a users table.
Concept: VPD This is a feature in the oracle database that allows a transparent implementation of security rules. In the application you'll define a simple select like
SELECT * FROM emp
But the VPD implementation will automatically add a where clause to the query to only show the records defined in the VPD policy. This makes developing the application a lot easier since there is less room for errors. Note that this database option could not be included for your licence. There is also something called "Poor Man's VPD" that does not use the VPD option. Google on how to implement this in your apex application.
Just do it all by hand: This is the least preferred option but it can be done. For every component where a select is done, manually add a where clause to restrict the returned rows. However this is very maintenance intensive and there is a ton of room for errors - obiously the data model will still have to support the striping of the data.
This blog post by Jeffrey Kemp might give you some pointers as well: https://jeffkemponoracle.com/2017/11/convert-an-apex-application-to-multi-tenant/ - go through the "further reading" section at the bottom.
you can create a procedure or function and in your app's shared components -> authorization scheme use that such as pl/sql function/procedure returning boolean and return true for the users you want to see the things and false for hiding.
In Apex components, select this authorization scheme like in items, pages etc.

At what point do you need more than one table in dynamodb?

I am working on an asset tracking system that also manages the concept of "projects". The users of this application perform maintenance activities on their customer's assets, so they need an action log where actions on an asset start life as a task in a project. For example, "Fix broken frame" might be a task where an action would have something like "Used parts a, b, and c to fix the frame" with a completed time and the employee who performed the action.
The conceptual data model for the application starts with a Customer that has multiple locations and each location has multiple assets. Each asset should have an associated action log so it is easy to view previous actions applied to that asset.
To me, that should all go in one table based upon the logical ownership of that data. Customer owns Locations which own Assets which own Actions.
I believe I should have a second table for projects as this data is tangential to the Customer/Location/Asset data. However, because I read so much about how it should all be one table, I'm not sure if this delineation only exists because I've modeled the data incorrectly because I can't get over the 3NF modeling that I've used for my entire career.
Single table design doesn't forbid you to create multiple tables. Instead in encourages to use only a single table per micro-services (meaning, store correlated data, which you want to access together, in the same table).
Let's look at some anecdotes from experts:
Rick Houlihan tweeted over a year ago
Using a table per entity in DynamoDB is like deploying a new server for each table in RDBMS. Nobody does that. As soon as you segregate items across tables you can no longer group them on a GSI. Instead you must query each table to get related items. This is slow and expensive.
Alex DeBrie responded to a tweet last August
Think of it as one table per service, not across your whole architecture. Each service should own its own table, just like with other databases. The key around single table is more about not requiring a table per entity like in an RDBMS.
Based on this, you should answer to yourself ...
How related is the data?
If you'd build using a relational database, would you store it in separate databases?
Are those actually 2 separate micro services, or is it part of the same micro service?
...
Based on the answers to those (and similar) questions you can argue to either keep it in one table, or to split it across 2 tables.

GraphDB account modeling: user access relationship attribute or relationship?

I am attempting to model account access in a graph DB.
The account can have multiple users and multiple features. A user can have access to many accounts. Each account can give access to only part of the features for each user.
One way I see it is to represent access for each user through relationship attributes, this allows having a shared feature node.
user_1 has access to account_1-feature_1 and account_2-feature-2. user_1 does not have access to account_1-feature_2 even though it is enabled for the account.
Another way to model the same access, but without relationship attribute is to create account specific feature nodes.
Question 1: which of these 2 ways is a more 'proper' modeling in the graph DB world?
Now to make things more interesting the account can also have parts which can be accessed by multiple accounts and a certain feature should be able to be scoped down to only be accessible for specific part by user.
In this example user_1 can access account_1 only for part_a feature_1.
To me it seems like defining an attribute on relationship is the way to go for being able to scope down user access by feature & by part of the account. However, reading neo4j powerpoints this would be one of the code smells of relationships having "Lots of attribute-like properties". Is there a better way to approach such problem in a graph?
I could be wrong here, but here are my thoughts. Option 1 definitely sounds the better way from a modeling perspective, however, I don't see how you can keep the data consistent without building heavy machinery to do it. For example, If someone deletes Account1.Feature1, and does not update the edge from User1 -> Account1, then you end up having stale RBAC rules in the system. You think you have access to something, but in reality that "thing" does not exist anymore. Option 2 may not seem very attractive from a data model perspective, but it does keep your data consistent. If you delete Account1.Feature1, the edge is automatically deleted in the same transaction.
The only con is that, you need to incur additional cost at insertion where you need to insert a lot more nodes than Option 1. For an RBAC system, I think its a fair compromise.
The same comment applies to the second half of your question as well.

How to implement content based authorization in ASP.net and SQL Server?

I am developing data application for governments, and I have a situation in which I need to make data shared to all users in one page but with different privileges levels that can control authorization based on locations, not just simple admins and viewers or editors roles.For Example, I have Locations Table that contains regions, cities, and districts in a hierarchal pattern, and all data will be displayed on the page will be affected by this location changes then the user who is authorized for a city can see only data related to this city and users can be authorized for multiple cities and multiple datasets within the page, If we maintained user inside a record then we need records number multiplied by authorized locations all multiplied by authorized datasets which can be infinity.So what's the best practice to store those user roles for each single data record related to specific location?
I'd have a look at row level security in the first instance. It allows you to set up security policies that allow different rows to be available to different groups/users.
Microsoft's thread for this starts here: https://learn.microsoft.com/en-us/sql/relational-databases/security/row-level-security
And there's also a good tutorial on Plural Site.
I'd post some examples but it's too broad a subject to answer here.
One point to note - there are performance limitations on row level security.
If security isn't as much of a concern then a mapping table and some clever joins is a popular way to go, and also much faster than row level security - depending on your data size.

Best Practices in User Privileges/Session Variables in MVC3

Hi Stack Community Members,
I am developing an application under MVC3 where users have department-specific CRUD privileges. In other words, all users can view data for all departments, but only certain users can make changes to the data for any one given department. User-department privilege data is held in a join table in a database.
What I typically do in this kind of situation (in PHP) is to create a Session variable (an array) on login which is populated with the id's of the departments which the user is allowed to edit. When a user then goes to access the editing feature a drop-down list is populated with only these specific departments. I also populate a few other session variables which are used frequently like the user's name and the id of the current time period (business quarter).
Is this type of approach a good way to go in MVC3, or is some alternative approach better? While I figure that I'm going to use Forms Authentication and some specific roles (employee, admin, etc.) these types of roles are just too broad to be able to target department-by-department access, and I'm not sure that MVC3 has an out-of-the-box method which is better than what I'm planning to do.
Your guidance is appreciated!
I'm using Forms Authentication, add specific roles, and combine them if needed. I don't mind being specific for the roles, as they can be combined anyway I want. I can still have broad roles for more general actions.
I store similar data (UserId, DepartmentId, etc) in session since it does not change for the user and it is a small amount of data. It is my opinion that session state would be a good approach for you also.

Resources