I am developing a project with MongoDB, I have a scenario, so that I can restrict the visibility of data to the user based on their role, for example if I have a document of the form:
{
"testme1":"fooo",
"testme2":"foobar"
}
A user with role "admin" can see both "testme1" and "testme2", whereas "guest" can see only "testme2". What is the best way to define these authorization rule dynamically, so that my wrapper api should fetch the data only as per the rule. My approach of doing is to give the user a web "UI" to define a rule and based on his declaration keep a "XML" file in my server. Please let me know if someone has a better Idea,also if their is some Database level approach to do this
There is an authorization standard that exists which you can use to define your authorization policies. This standard is called XACML, the eXtensible Access Control Markup Language. It implements an authorization model called attribute-based access control (ABAC). You can read up on both topics here:
NIST's page on attribute-based access control (ABAC)
OASIS extensible access control markup language (XACML)
XACML defines an architecture with the notion of:
a policy decision point (PDP),
a policy enforcement point (PEP), and
a policy information point (PIP).
In the typical flow, the PEP protects your data / service / API. The PEP would send an authorization request to the PDP:
Can user Alice view record #123?
The PDP would turn to the PIP to retrieve missing attributes e.g. the user's role and clearance as well as resource attributes e.g. the sensitivity of data, a whitelist or blacklist... Based on the new information, the PDP can reach a decision: Permit or Deny. Access is allowed or blocked.
With XACML there is no limit to the richness of the authorization policies. I work for a company, Axiomatics, that implements XACML, and our solutions are used in manufacturing, healthcare, banking to secure access to sensitive data in a dynamic way (e.g. managers can edit documents that they own).
XACML enables externalized authorization that is managed centrally. It also enables what I like to call any-depth authorization meaning that you can apply XACML to web APIs, business logic, presentation UIs, as well as databases.
HTH
Related
The problem to face lies in the design of a RESTful API that can manage requests from multiple roles in an RBAC-based solution.
Currently we have different resources that can be accessed from different users, which can have one or more roles grouped according to their privileges.
The API we're trying to define must be as clear as possible to the client but without the overhead of adding additional metadata to the URL that could damage and even conflict with the REST practices and definitions. Therefore, we must avoid at all costs include information about the roles inside the URL. The plan is to use JWT tokens that carry in their payloads the info needed to know which permissions has the user making the request.
Having raised our current situation, let's provide an example and state the problem to solve:
Suppose we have * financiers * and * providers * as users with some roles who both want to access ** attentions ** (our resource). Should we add before the resource ** attentions ** information about the * user * whose trying to access the resource?
The endpoints in that case should be defined (as an example) as:
https://example.com/api/v1/financiers/:id/attentions
https://example.com/api/v1/providers/:id/attentions
This way we're attempting to inform the respective controllers that we want the ** attentions ** for that specific role / user which are, in some way, a sub-resource of them.
On the other hand, we could simply implement a much simpler endpoint as follows:
https://example.com/api/v1/attentions
The logic about which attentions return from the database should be now implemented in an unique method that must handle this two roles (and potentially new ones that could come up in the following features). All the information needed must be obtained from the payload from the token, exposing a much more generic API and freeing the web client from the responsibility of which endpoint call depending on the role.
I want to highlight that the attentions are managed in a Microservices Architecture and, hence, the logic to retrieve them is gathered in a single service. The cost of the API Gateway to route the two (and potentially more) of the endpoints from the first solution is a variable not to discard in our specific situation.
Having exposed our current situation:
Which we'll be the best approach to handle this issue?
Is there another alternative not contemplated that could ease the role management and provide a clean API to expose to the client?
In the second solution, is correct to return only the attentions accessible to that specific user based on the roles that it has? Isn't it counterintuitive to access an endpoint and only get some of the resources from that collection (and not all) based on its role?
I hope that someone could clarify the approach we're taking as there are little and none literature that I've found regarding this issue.
There there are multiple solutions for such kind of filtration, and developer have to select one depending on given situation.
As per my experience I can list following.
Structure
When data can't be accessed directly and developer has to use a relation (i.e a table JOIN). In that case URL have to include both the main and sub entities. Before going with this approach a good check is to ask, if the same URL can be used with POST ?
Example
If we have to fetch list of roles assigned to a specific user or want to assign additional roles then we can use
GET users/:uid/roles
POST users/:uid/roles
Security
With Multi-tenant systems where each user can have his/her private resources, i.e other users are prohibited from accessing those resources. Developer should save tenancy information and to filter the resources according to current authentication, without bothering client or requiring any additional info in URL
Example
Phone album of the user
GET photos
POST photos
Search
If it is not security or structure related but client still want to filter the result set depending on his scenario. then developer should use query-string for the filtration.
Example
Client have to fetch messages from his/her inbox or outbox or want messages which are not yet read. or he/she want to search his/her inbox
GET messages?folder=inbox
GET messages?folder=inbox&status=unread
GET messages?search=nasir
So, I am working on the next project that requires more detailed access control functionality (i.e. Sally can only view products in her department).
I get how either a role based access control model or an attribute access control model can 'wrap' an API call to determine if a given user can perform said action on a given object.
Where I keep getting stuck is when you are dealing with a GET call that returns a collection of records. If I ask the API for a page of 20 records from this endpoint, I can't get 20 records, then run a code based authorization check on those records before returning them as I most likely won't be returning 20 records.
It seems like the authorization check either has to be down in the database and/or happen prior to the database query by adding additional filters to the query call (i.e. also filter where product department = clothing).
Anybody have any more concrete implementation examples or ideas how how this could be implemented in a performant manner?
As David mentioned, XACML can be used at the database level for filtering.
Implementing XACML For The Database
The diagram below is for SQL, but can be used as a general example for any database technology.
Let's see how this works:
SQL statement is intercepted.
A query is sent to the external authorization service that implements XACML
The authorization engine (PDP) evaluates the relevant policies, written in XACML or ALFA (an implementation of XACML).
It may query external attribute sources (PIPs) for more info.
The result: SQL statement is dynamically modified to retrieve only authorized data for the user.
How This Would Be Used In An Application
The implementation of XACML you choose to go with would ideally have an SDK in your language of choice or support the XACML REST profile. Either would work for integration into your application.
Given that you are using REST calls, I don't think you would have to add much code to integrate your application with an implementation of XACML.
Implementing XACML for an API Gateway
The principle used in this integration is the ability of an API gateway to make a callout to a third party service.
In this case the third party service is your XACML implementation's Policy Decision Point (PDP). The implementation must support REST/JSON.
The API Gateway is configured to send fine-grained authorization requests to the PDP.
Requests are made using the REST/JSON interface exposed by the PDP. The PDP then returns a response.
The JSON profile of XACML extends the Request/Response schema allowing both the Request and the Response to be encoded in JSON instead of the traditional XML encoding. This makes the Request and the Response much easier to read and also much smaller in size thus transferring less data.
Implementations of XACML
For an entire list of XACML implementations, you can check this list on Wikipedia.
Full disclosure - I work for Axiomatics with David Brossard, who designed the JSON profile for XACML to be used in conjunction with the REST profile.
Axiomatics provides Axiomatics Data Access Filter for relational databases and SmartGuard for HADOOP. Axiomatics Policy Server natively supports both JSON and REST profiles.
I have generated JAX-RS stubs for a REST service using Swagger and want to set up the security.
The security side is very new to me and I would like to use standards as far as possible. (In the past, for other J2EE applications, I have used Filters to handle Authentication which put User objects into a Session. As I understand it, Sessions should be avoided for REST.)
There are 4 types of user who will access the services
Customers and business partners (Authentication via oAuth or similar)
Employees (Authentication via NTLM & LDAP)
Developers (Mock authentication/authorisation of some kind)
Integration test (JUnit with pre-defined users and roles)
Is it possible to define a security mechanism which would handle all of these users?
How would I use the Swagger security directives?
Am I making this more complicated than it needs to be?
You could use an open source API gateway like Tyk? Here’s a link to some handy info on API Security in the tyk docs.
And here is a blog post that describes taking a layered approach to API Security that goes beyond the gateway.
Disclosure: I work for Tyk!
Standard way to control access in a multi user service is to provide as many service methods as necessary, where each service method has concrete results and access permissions.
For example,
Moderator is authorized to call GetModerationAwaitingPosts service method to access posts from any visitor awaiting for moderation
Visitor is authorized to call GetOwnedPosts service method to access only his own posts including draft and moderation awaiting posts
Visitor is authorized to call GetModeratedPosts service method to access only moderated posts from all visitors
But there may be another approach - single service method GetPosts to request posts that the requester is allowed to see.
Any logged in user is authorized to call this method.
Posts are first filtered according to the role of the caller.
Then posts are filtered according to parameters passed in GetPosts method or filtered on client side.
This approach is used, for example, in WCF Data Services through Query Interceptors.
How is approach to filter data based on user inside service method named and treated in different architectures and methodologies, like SOA, REST, CQRS? Is it a solid solution?
Are there any books / articles where difference between these approaches is considered in details?
As for me, I find it really strange and unusual when results of a request depend on the requester.
Yes, there is an access control paradigm called attribute based access control (ABAC, abac) which implements data-based, context-based authorization that uses information about the user (role, department, age, location...) about the resource (owner, classification, type...) action (view, edit, delete), and context (time, IP address...)
ABAC will let you implement policies e.g.:
Medical use cases
doctors can view the medical records of patients they are assigned to
nurses can edit the medical journal of a patient in the same deparment
Finance use cases
A teller can view the accounts of those customers in their branch
A teller can approve a transfer up to their approval limit
ABAC provides an architecture as depicted below.
In the architecture you have the notion of a PEP or policy enforcement point which you can use to secure anything from GUIs, APIs, web services, micro-services, ESBs, and databases.
The PEP calls out to the PDP or policy decision point which is at the core of the architecture. The PDP uses a set of policies to determine whether access should be granted or denied. It can also use external sources of attributes, PIP or policy information points, to help in determining whether access should indeed be granted.
There is one language which implements ABAC today. This language is called XACML (xacml). XACML gives you:
the architecture
a policy language
a request / response scheme
With XACML you can create JSON authorization requests, send them off to the PDP and get a JSON response back. It's an extremely lightweight way of getting a response back.
This means you can either
grant or deny access to a given record, or
filter those records a user can get access to as stated in your requirement
I am designing a REST API with consumers that have different permissions. I understand that a representation of a resource should not change according to user. Therefore I am trying to determine which is the best approach:
GET - list collection of all documents - admin only.:
/api/documents
GET - list collection of all documents - any user with access to document 123
/api/documents/123
For normal users therefore should the endpoints be
list all documents for user 12
/api/user/12/documents
document 123 assuming user 12 has access
/api/documents/123
OR... should the end points be as below and a query string filter used:
/api/documents?user=12
/api/documents/123
In this case you can get away with just two endpoints (and one header!). Make sure the API for /documents is returning the Vary: Authorization header. Then you can use
GET /api/documents // return all docs the logged-in user can see
GET /api/documents?userId=bob // return all of bob's docs that the logged-in user can see
GET /api/documents/123 // return doc 123 if the logged-in user can see it
It is not entirely unreasonable to nest the user a la GET /api/users/bob/documents. I find it to be harder for end users to learn APIs with a large number of endpoints, and I feel that the nested approach tends to create many endpoints. It's conceptually easier to go to /documents and see what you can filter on, rather than look at each endpoint and see what filters it has.
I would keep business logic and authorization logic entirely separate. If you want to retrieve document XYZ, you wouldn't pass the user id as an HTTP parameter.
You suggested /api/documents?user=12 but in fact it should just be /api/documents. The user information should come from the authentication layer.
Similarly authorization should be entirely separate. The reasons for that are:
separation of concern
ability to update authorization logic independently of of business logic
avoid impact on API design
The API should only reflect those business objects you care about e.g. documents in this case (possibly also users should you wish to display a user profile...).
To handle authentication, use the container's standard techniques (e.g. HTTP Basic authentication) or use advanced authentication techniques (OAuth..) via a dedicated framework.
To handle authorization, use a filter, an interceptor. In the Java world (where JAX-RS implements REST), have a look at the Jersey interceptors and filters. You then want the interceptor (or policy enforcement point - PEP) to query an external authorization service (or policy decision point).
Have a further look at ABAC, the attribute-based access control model, and XACML, the eXtensible Access Control Markup Language which explain how to control access to your REST APIs without mixing business logic and authorization logic.