How do you implement authorization for a list of resources?
All docs I see are based on IAuthorizationService and the AuthorizeAsync methods. But this, only applies to one resource.
Should I be retrieving all resources and then imperatively check if the user has access or not using the AuthorizeAsync method of the IAuthorizationService? This seems very ackward, slow and inneficient.
How would you do this?
I have implemented this in few of my projects and aside from fetching all resources from the database and then executing AuthorizeAsync on each of them there is not much that you can do (so far as I know).
In some cases you can have mapping table in the database that stores resourceId/userId and check according to that. It is easier to fetch items that way without executing AuthorizeAsync on each, but it is not applicable in each scenario...
There are a few questions on this subject (such as https://github.com/dotnet/AspNetCore.Docs/issues/10244) but no solution.
Related
How to refresh the interface after you add a strip of data to the backend database in Vue.js?
I mean, if I add a item data to the database. there are two case for refresh the interface.
refresh the list api to get the page data.
append the added item data to local list.
what is the best way to do this?
I think both the solutions are valid it depends on what kind of write operation we are planning to do. Given that you do all the validations on the front-end which leaves lesser chance for errors on the backend. I do the following based on the use case.
Add/Update the item locally and then based on the response from the server I remove it again in case of an error. This is an optimistic technique used by a lot of websites and worls really well for CRUD kind of operations.
Let's say that your new operating is going to creaate a new user in a 3rd party api. So doing an optimistic thing might not be the best. So what I do is make the request, show a toast/alert that the request is happening, and then use sockets or long polling to get the changes. When the request is finally done show the data. In the meanwhile you can insert a dummy item showing loading.
I came across many different models for the Access Control in a system. When implementing an Access Control model in any system, we usually hard code the rules/rights in the database(considering an RDBMS) by creating separate tables for the Access Control. Also, these rules/rights can be stored in an XML database.
I would like to know what is the difference between storing the rules on RDBMS and on an XML database? Also, when should we use XACML for implementing an Access Control model in a system? I mean, how one can decide whether one should hardcode the rules/rights in the database or one should use XACML policy language?
Thanks.
Disclaimer: I work for Axiomatics, a vendor implementation of XACML
Storing authorization logic if you go your own way could be done either in the RDBMS or in an XML database. It doesn't matter. I doubt that XML brings you any added capabilities.
Now, if you want an authorization system that can cater for RDBMS systems and other types of applications too (CRM, .NET, Java...) then you want to use a solution that is agnostic of the type of application it protects. That's the goal of XACML, the eXtensible Access Control Markup Language.
XACML provides attribute-based, policy-based access control (ABAC and PBAC). This gives you the ability to write extremely expressive authorization policies and managed them centrally in a single repository. A central authorization engine (called Policy Decision Point or PDP) will then serve decisions to your different applications.
As Bell points out, the minimum set of attributes you will need is typically attributes about the user (Subject), the resource, and the action. XACML also lets you add environment attributes. This means you can write the following type of policy:
Doctors can view the medical records of patients they are assigned to.
Doctors describes the user / subject
view describes the action
medical records describes the targeted resource
of patients describes the targeted resource too. It's metadata about the resource
they are assigned to is an interesting case. It's an attribute that defines the relationship between the doctor and the patient. In ABAC, this gets implemented as doctor.id==patient.assignedDoctorId. This is one of the key benefits of using XACML.
Benefits of XACML include:
- the ability to externalize the authorization logic as mentioned by Bell
- the ability to update authorization logic without going through a development/deployment lifecycle
- the ability to have fine-grained authorization implemented the same way for many different applications
- the ability to have visibility and audits on the authorization logic
HTH
The two are not mutually exclusive.
An XACML policy describes how to translate a set of attributes about an attempted action into a permitted/denied decision. At minimum the attributes would be who the user is (Subject), what they are trying to do (Action) and what they are trying to do it to (Object). Information such as time, the source of the request and many others can be added.
The attributes of the user and the object will still have to be stored in the database. If you are grouping users or objects to simplify administration or to simplify defining access control rules then you're going to have to manage all of that in the database to. All that data will then need to be passed to the XACML Policy Decision Point to return the permit/deny decision.
The advantage of using XACML to define these rules, rather than writing your own decision logic for the rules defined in the database, is that the assessment of the rules can be handed off to an external application. Using a mature, tested XACML implementation (there are open source options) will avoid you making any mistakes in building the checks into your own code.
Hardcoding the policies in your code is a very bad practice I think. In that case you mix the business logic of your resources and the permission check of the access control system. XACML is a big step in the right direction because you can create a fully automatic access control system if you store your rules in a separated place (not hardcoded in the business logic).
Btw you can store that rules in the database too. For example (fictive programming language):
hardcoded RBAC:
#xml
role 1 editor
#/articles
ArticleController
#GET /
readAll () {
if (session.notLoggedIn())
throw 403;
if (session.hasRole("editor"))
return articleModel.readAll();
else
return articleModel.readAllByUserId(session.getUserId());
}
not hardcoded ABAC:
#db
role 1 editor
policy 1 read every article
constraints
endpoint GET /articles
permissions
resource
projections full, owner
role 2 regular user
policy 2 read own articles
constraints
endpoint GET /articles
logged in
permissions
resource
projections owner
#/articles
ArticleController
#GET /
readAll () {
if (session.hasProjection(full))
return articleModel.readAll();
else if (session.hasProjection(owner))
return articleModel.readAllByUserId(session.getUserId());
}
As you see the non hardcoded code is much more clear than the hardcoded because of the code separation.
The XACML is a standard (which knows 10 times more than the example above) so you don't have to learn a new access control system by every project, and you don't have to implement XACML in every language, because others have already done it if you are lucky...
I'd like to keep a log of all searches that users do on my site which uses the sunspot-rails gem. I don't need the logs to be real-time accessible by my application as they're for analytics that will be processed later.
I'm thinking that I should do the logging in rails rather than in solr itself so that I have access to the entire session, but I'm not sure how to build that. Is there a standard method for this? I saw this question but I would think there would be something more generic than writing it all myself in ApplicationController.
The ultimate answer depends on howwhere you're implementing your search. If you have a single search controller, do the logging there. If you have a collection of search controllers, either do it in each one, or create a base class, do the filter/logging in the base class.
Can you provide any more details?
An example problem:
On Stack Overflow, a question page shows a number of different answers. In displaying these answers, the site also gives information about the author of the answer. This means that although the number of badges a given user has has nothing to do with an answer in and of itself, that data still needs to be retrieved in order to display the page.
From what I can see, there are three different ways to go about pulling this view data in a model:
A Post object could include a full User object as a member. The view would then access the user like this: $post->user->getReputation(). This seems cleaner, since a Controller could just request the posts and be done with it, but yet inefficient since a Post probably doesn't always need a full-blown User. I suppose it works well enough if the User object is relatively light, which it probably would be. The problem would then be that you would need to duplicate User retrieval code as part of the Post retrieval query.
The Post object could hold just an ID for a User. When the Post, or Posts, are returned to the Controller, the Controller could then extract the unique User IDs from the returned set and pass them to a User factory. The returned User objects would then be passed along with the original Posts set to the View as a separate collection. The view could then grab user info using something like $users[$post->getUserId()]->getReputation().
A hybrid approach: Include the User object inside the Post object, but have the unique id extraction and User retrieval as part of the Post retrieval method. i.e. Post::getPosts() would grab all relevant posts and convert them to objects with null User members, then it'd extract all user ids and pass them to User::getUsers(), then assign the Users to the relevant Posts before returning the set of Posts to the caller.
I guess what I'm getting at is, how do I know when an object needs to contain another object fundamentally? Is it unclean/a code smell to instead have such related objects returned separately, with neither object knowing the other has been retrieved. I'm leaning towards the separate retrieval concept - it seems the most efficient - but it really does feel like they're too related for that to make sense.
There is also a solution in between 1 and 2. You can have a lazy loading proxy for the user class. With this solution you can have best of both worlds because the proxy is interchangeable with the real thing so depending on the situation you can have the object itself or the proxy.
Edit:
I'll try to explain this with an example.
Say that you have a view where you don't need user info, then you can instruct/configure your post factory to use the lazy proxy (see wikipedia)for the user which will only contain an ID. So no access to users is needed.
In another view you occasionally need to access user info but only for some posts, here again you instruct/configure your factory to include the lazy proxy for the user.
But when you actually need access to the user info, you can access the proxy object that will then load the actual user object and redirect messages to it.
In yet another view you need both post and user info, so here you instruct your post factory to use actual user objects.
It seems to me that this is another case of dependency injection. A general enough idea that could help you.
DEPENDENCY INJECTION WIKI
Read something about the Inversion Of Control also.
why not add optional member to model to know informations?? you can ignore when you don't need and can use when you do need.
I'm a new REST convert and I'm trying to design my first RESTful (hopefully) api and here is my question about addressing resources
Some notes first:
The data described here are 3d render
jobs
A user (graphics company) has multiple projects.
A project has multiple render jobs.
A render job has multiple frames.
There is a hierarchy enforced in the data (1 render job
belongs to one project, to one user)
How's this for naming my resourses...?
https:/api.myrenderjobsite.com/
/users/graphicscompany/projects
/users/graphicscompany/projects/112233
/users/graphicscompany/projects/112233/renders/
/users/graphicscompany/projects/112233/renders/889900
/users/graphicscompany/projects/112233/renders/889900/frames/0004
OR a shortened address for renders?
/users/graphicscompany/renders/889900
/users/graphicscompany/renders/889900/frames/0004
OR should I shorten (even more) the address if possible, omitting the user when not needed...?
/projects/112233/
/renders/889900/
/renders/889900/frames/0004
THANK YOU!
Instead of thinking about your api in terms of URLs, try thinking of it more like pages and links
between those pages.
Consider the following:
Will it be reasonable to create a resource for users? Do you have 10, 20 or 50 users? Or do you have 10,000 users? If it is the latter then obviously creating a single resource that represents all users is probably not going too work to well when you do a GET on it.
Is the list of Users a reasonable root url? i.e. The entry point into your service. Should the list of projects that belong to a GraphicsCompany be a separate resource, or should it just be embedded into the Graphics Company resource? You can ask the same question of each of the 1-to-many relationships that exist. Even if you do decide to merge the list of projects into the GraphicsCompany resource, you may still want a distinct resource to exist simple for the purpose of being able to POST to it in order to create a new project for that company.
Using this approach you should be able get a good idea of most of the resources in your API and how they are connected without having to worry about what your URLs look like. In fact if you do the design right, then any client application you right will not need to know anything about the URLs that you create. The only part of the system that cares what the URL looks like is your server, so that it can dispatch the request to the right controller.
The other significant question you need to ask yourself is what media type are you going to use for these resources. How many different clients will need to access these resources? Are you writing the clients, or is someone else? Should you attempt to reuse an existing standard like XHTML and classes/microformats? Could you squeeze most of the information into Atom? Maybe Atom with some extra namespaces like GDATA does it? Or is this only going to be used internally so you can just create your own media types, like application/vnd.YourCompany.Project+xml, application/vnd.YourCompany.Render+xml, etc.
There are many things to think about when designing a REST api, don't get hung up on what your URLs look like and you should really try to avoid doing "design by URL".
Presuming that you authenticate to the service, I would use the 1st option, but remove the user, particularly if the user is the currently logged in user.
If user actually represents something else (like client), I would include it, but not if it simply designates the currently logged in user. Agree with StaxMan, though, don't worry too much about squeezing the paths, as readability is key in RESTful APIs.
Personally I would not try to squeeze path too much, that is, some amount of redundant information is helpful both to quickly see what resource is, and for future expansion.
Generally users won't be typing paths anyway, so verbosity is not all that bad.