As already pointed out, Niclas was talking about code security and not
AAA security, but this is important too:
Aye wrote:
The one thing I've noticed in other frameworks is that they treat
security outside of a domain context. Static security models at
service level and/or domain object levels are good but I think it
paints only a part of the picture. For example, imagine a case where
the user is allowed to issue a command/invoke a service; but the
constraints are that he/she can do this from 9 AM to 5 PM. This
doesn't even take into consideration what state the domain object in
question is in (e.g. 'Active' status). In my mind the domain context
in which the request is made is very important and that having a
role(or permissions) is just a starting point. I've seen a lot of IF
statements where the permission is checked AND then a dozen more
conditions that are domain specific is checked. In my mind they're all
together and is a part of the security model.
Completely agree!
Ok, next. Let's say that the user got the authorization to issue the
command successfully; the domain object (or objects) returned should
also have authorization metadata associated with its properties so
that the GUI (or another client) is able to figure out what can be
changed and what can't be. I actually think qi4j might already be
handling this with the Property interface (@Immutable also).
Agree. The way I'm doing this in StreamFlow is like this: the domain
model is only running on the server, and is exposed through
domain-oriented REST endpoints (implemented using Restlet). Each object
will have authorization checks for general access, and then each
operation will be a subresource of its own, which can be GET or HEAD in
order to check availability. If it returns 200 then a) the operation is
valid from a domain state point of view and b) the user actually has
authorization to perform it. If not a) then 404, and if not b) then 401.
In both cases the UI can detect this and change the UI for it.
Example:
inbox/task/{id}/complete
=> GET gives form for completing the task
=> HEAD checks availability and security
=> POST performs the command
Actual implementation on the server would be:
Task.complete(CompleteTaskCommand)
where CompleteTaskCommand is a ValueComposite so it is easy to
generically create a form or post as JSON.
Doing GET on /inbox/task?{task query} will retrieve a listing which
contains the specific details needed to show an overview of the inbox.
That operation is:
Inbox.task(TasksQuery)
where TasksQuery is a ValueComposite.
This achieves both RESTfulness, domainlevel RBAC, CommandQuery
separation (complete is command, task is query), and other goodness.
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev