Timeline for Implementing DDD: users and permissions
Current License: CC BY-SA 3.0
40 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Jul 8, 2021 at 0:45 | comment | added | Tez | Udemy is an example of resource based authorization where roles would not suffice since student only have access to lectures if they have paid for it, and the has paid attribute is dynamic. | |
| May 28, 2019 at 21:00 | comment | added | Jordan | I'm not saying I know this is right or that I've done this before and I realize it challenges conventional wisdom, but I've been thinking about this a good deal and the biggest issue I've found with this approach is in cases where your authorization checks have to call to an external service (perhaps the permissions are too large to populate in the context which might be an issue if you're doing something like cross-account actions). | |
| May 28, 2019 at 20:47 | comment | added | Jordan | @Ewan I'm not suggesting either of those - I'm suggesting at a "higher" application layer, like in your middleware, you're doing your authentication and authorization. This is where you'll populate the user information and permissions or, if you have a special case for systems or admin users that bypass authorization checks, you would still authenticate them properly and add something to the context indicating the action is being done on behalf of an admin user or system that has "god" mode. Ideally you'd still tie those users or systems to roles and populate their permissions accordingly. | |
| May 28, 2019 at 19:53 | comment | added | Ewan | @Jordan im not sure if you are suggesting a duplicate object without the auth or a backdoor in the auth which enables bypassing. obvs both are bad | |
| May 28, 2019 at 19:51 | comment | added | Jordan | @Ewan this could be handled outside of the domain (when populating user info, claims/permissions, etc...) then your authorization method would check the context for a bypass | |
| May 28, 2019 at 19:15 | comment | added | Ewan | @Jordan in the case of the admin function there may not even be a user at all. Its going to be something completely outside your normal system, eg, back up data, calculate taxes owed, produce access log audit etc | |
| May 28, 2019 at 19:12 | comment | added | Jordan | @Ewan - This would come down to the qualifier check - e.g. either they need to have access to update “all” or “own” | |
| May 28, 2019 at 19:07 | comment | added | Ewan | @Jordan the counter example for #2 is that you may well have an Export or other admin function which is supposed to bypasses all the security checks. But having embedded them in the Business logic you are unable to do so. | |
| May 28, 2019 at 19:05 | comment | added | Jordan | @Ewan fair point on #1, but I'm not sure I'm convinced on #2 for resource based authorization where you have something like a resource, action and qualifier such that you would check, for instance if someone has the permissions to update (action) an order (action) only if it's their own (qualifier). You might have multiple service methods that call the same method on your domain model. Why should each of these services have to repeat the same authorization check when you could embed this check, as part of the business logic, in the model itself? Could you provide some counter examples? | |
| May 28, 2019 at 18:10 | comment | added | Ewan | @Jordan the problem is two fold. 1. its easy to be lead into reinventing the wheel, when role based auth is out of the box and can cover 99% of cases. and 2. security is cross cutting concern. If you embed it in a layer lower than the top most you can run into issues very quickly. | |
| May 28, 2019 at 16:46 | comment | added | Jordan | "Authentication and Authorisation is a bad example for DDD. Neither of these things are part of a Domain unless your company creates security products." This is a fair point, but it doesn't mean these things aren't part of your business logic. It may be silly to do things like authentication or populating or user info/permissions/claims info in the domain layer (things that are common to every call), but I'm not sure why it would be so wrong to put authorization logic in your domain model or in a domain service especially if you're doing something like resource based authorization... | |
| Mar 28, 2019 at 16:26 | comment | added | Réda Housni Alaoui | I have no other way than ask questions to understand the design you are defending. If you don't want to answer questions, maybe you are on the wrong site :D | |
| Mar 28, 2019 at 16:13 | comment | added | Ewan | are we designing an entire social media app through a series of questions? | |
| Mar 28, 2019 at 16:07 | comment | added | Réda Housni Alaoui | How does the controller know it? | |
| Mar 28, 2019 at 15:52 | comment | added | Ewan | no the controller only knows if the post is a "normal" or "moderator" post | |
| Mar 28, 2019 at 15:52 | comment | added | Ewan | to take your groups that can edit groups example you have n^2 permissions. Sure you code can correctly apply them, but can a human check to see if someone in a group of bad actors can edit a group in the set of sensitive groups | |
| Mar 28, 2019 at 15:46 | comment | added | Réda Housni Alaoui | But let's explore the more static case with "You simply expose methods EditNormalUsersPost and EditModeratorsPost and limit to the appropriate roles". You have to check that the user is normal or moderator in the controller then? I feel that the controller should be as dumb as possible and should not be smart enough to know if user is a moderator or a normal user. Or do you do it using another method? | |
| Mar 28, 2019 at 15:43 | comment | added | Réda Housni Alaoui | "But it's generally recognised as a "bad thing" your security settings become unmanageable over time which effectively means your app becomes insecure." With the correct design and test, it is totally manageable. But, from my XP, to produce the correct design, the domain must check the permission. The alternative is utopia. | |
| Mar 28, 2019 at 15:33 | comment | added | Ewan | It is possible that in some circumstances you will have to implement that kind of thing in order to meet a requirement. But it's generally recognised as a "bad thing" your security settings become unmanageable over time which effectively means your app becomes insecure. You are basically saying that the feature is more important than security. Which might be true, but is not generally good to assume | |
| Mar 28, 2019 at 15:27 | comment | added | Réda Housni Alaoui | IMHO, the issue with your solution is that it does not satisfy the customer. The customer often want to be able to change those relations dynamically. Moreover, that's also what happens when a vendor provides the same enterprise software to different companies. If the software is poorly tweak-able, the vendor will eventually die. | |
| Mar 28, 2019 at 15:21 | comment | added | Ewan | The problem with the kind of dynamic role assignment you describe is that it leads to infinite roles. It's permissions based authentication. You can do it, but you end up with massive grids of checkboxes against users/permissions. You are better off sticking to Role based auth and defining your rule less dynamically with EditPostInAGroupImAMemberOf or whatever nearest approach you can get | |
| Mar 28, 2019 at 15:16 | comment | added | Réda Housni Alaoui | @Erwan, the use case I am talking about is dynamic. Basing the sentence "Authentication and Authorisation is a bad example for DDD" on hello world examples is dishonest. DDD is here to avoid accidental complexity and allow to manage domain complexity. Dynamic permissions is not an accidental complexity nor something that does not happen in real life. | |
| Mar 28, 2019 at 15:13 | comment | added | Ewan | please read my answer to your comment above.. oh wait | |
| Mar 28, 2019 at 15:12 | comment | added | Réda Housni Alaoui | Please read my edited comment above :) | |
| Mar 28, 2019 at 15:11 | comment | added | Ewan | it isnt dyanmic | |
| Mar 28, 2019 at 15:10 | comment | added | Réda Housni Alaoui | @Erwan ,what if this authorization is dynamic? Imagine a UI allowing to define user group by configuration. Imagine also that the user can decide to let a group modify the posts of another group by configuration. In that case you can't create one method per possible combination. | |
| Mar 28, 2019 at 14:54 | comment | added | Ewan | You simply expose methods EditNormalUsersPost and EditModeratorsPost and limi to the appropriate roles | |
| Mar 28, 2019 at 14:22 | comment | added | Jimmy | @RédaHousniAlaoui I'm wondering about this as well. I can't think of a way to handle this other than either including some mention of Users/Moderators in the domain, or performing some kind of logic within that ApiController to get the post's author's role. Neither of these seems right, and this is a common enough sort of thing in my experience that some clear guidance would be extremely helpful. | |
| Dec 22, 2018 at 11:41 | comment | added | Réda Housni Alaoui | Checking role "statically" is a little bit simplistic. What if a moderator is not allowed to edit the post of another moderator? Shouldn't this check be part of the domain? | |
| May 15, 2018 at 10:55 | comment | added | Ewan | @geoc they dont, one edits only the users posts, one edits posts belonging to other users. the implementation will be similar to be sure, but not the same. the differnet methods will be mapped to different use cases. the exact limitation about who can use which method is left to the security implementation. outside the business logic domain | |
| May 15, 2018 at 10:50 | comment | added | Geo C. | @Ewan I have to disagree with you. Your two examples do not offer any insight about what actually happens in your domain. Why would there be two methods that do the same thing "edit a post". In order to differentiate between the actions and teh conditions for that action to be fulfiled, you need to show in your domain who exactly does the action. Otherwise you would end up with the same statements inside the method's / action's body in your domain objects. | |
| Mar 14, 2018 at 20:01 | comment | added | Ewan | you need to secure your services before even the code is executed, you also want to prevent your client making calls that you know will fail. So the server is mandatory, the client is optional. If you use a token with claims you can do both | |
| Mar 14, 2018 at 19:08 | comment | added | LittlePilgrim | After the edits (and digesting the pieces) I think I'm starting to see your point. My question was more about where the role mapping/permission checking should happen. Author, Moderator, etc. are in the ubiquitous language, while User and Role are not: I need to do the mapping. If I'm not mistaken, you suggest doing this outside the domain objects and services, even before calling the service methods. On the other hand, wouldn't this (moving this code out of the application services) result in code duplication if there are multiple clients (e.g. a REST API and a web client?). | |
| Mar 14, 2018 at 16:59 | history | edited | Robert Harvey | CC BY-SA 3.0 |
deleted 57 characters in body
|
| Mar 14, 2018 at 16:51 | history | edited | Ewan | CC BY-SA 3.0 |
added 624 characters in body
|
| Mar 14, 2018 at 16:45 | history | edited | Ewan | CC BY-SA 3.0 |
added 624 characters in body
|
| Mar 14, 2018 at 16:40 | comment | added | LittlePilgrim | I agree with you that Authentication and Authorization are outside the core domain. However, they must be implemented somehow, as the are critical to business. I might use a prepurchased/open source component, but my problem is exactly this: how can I communicate with this supporting/generic subdomain without the concepts bleeding into the core domain? | |
| Mar 14, 2018 at 16:40 | history | edited | Ewan | CC BY-SA 3.0 |
added 292 characters in body
|
| Mar 14, 2018 at 16:33 | comment | added | user3347715 |
This answer is spot on. Authentication and Authorization are simply outside the concern for most DDD systems. I would only add here, that it may be preferable to, instead of just functionally mapping roles to different methods, create new Entities that are responsible for privileged actions (Visitor vs RegisteredUser vs AdminUser for a web-based example). Conceptually, I find this approach easier to understand. I also have found that it provides a cleaner separation of actions/validations.
|
|
| Mar 14, 2018 at 16:15 | history | answered | Ewan | CC BY-SA 3.0 |