4

Domain Examples :

1.

class Customer {
    public $id;
    public $purchaseLimitReached = TRUE;
}

class Order {
    public $customer;

    public function Order(Customer $customer) {
        if($customer->purchaseLimitReached === TRUE) {
            throw new Exception('Order cannot be created, customer   
                has reached his limits!');
        }
    }
}

2.

class User {
    public $email;
    public $emailOwnershipVerified = FALSE;
}  

In case 1, should the rule that an order cannot have as reference a customer that has reached his purchase limit be part of the domain, in the order object? Or should this rule be part of the authorization, that is handled outside the domain?

In case 2, if the User has not veryfied himself (the email), he has no right over any associations/reference in the domain. He cannot authenticate, post, comment, or even view private/hidden data. Should the domain objects have checks that enforce a valid reference/association to a User? Or should the verification that a User has verified himself be part of the authorization, again outside the domain?

Tudor
  • 1,133
  • 1
  • 12
  • 28

3 Answers3

1

Long story short , think about authorization mostly as business ruless and model your domain to reflect all these rules. The line between the real authorization and business rules is very thin, but one should try to forget about authorization for a bit and try to think mostly about business rules. Authorization is a technical concern , and is a very thin layer in my opinion.

Tudor
  • 1,133
  • 1
  • 12
  • 28
0

I think you could introduce a domain authorization layer standing on top of your pure domain and acting still in terms of the domain. Within your pure domain, any actions and references are always authorized, and it will be working this way when your authorization security is 'off', because the pure domain will not depend on the authorization layer. With authorization 'on', you enforce security specific checks performed by your authorization services. The final beauty of how it will look will depend on what machinery you will be using for 'intercepting' the domain behavior in order to enforce authorization rules (domain objects/services decorators, weaving-in of security-specific aspects etc.).

Look also at the answer to a similar question: https://stackoverflow.com/a/23300337/1512875.

Community
  • 1
  • 1
Pavel S.
  • 1,202
  • 1
  • 13
  • 29
  • Having another "middle man" or decorator or wrapper to enforce a rule that is explicit in my mini domain example seems improper. I just see 2 cases here (no middle man neede) : either you keep all authorization outside the domain (an authorization layer that would allow/deny user actions) or inside the domain objects themselves. The main problem is where to draw the line between domain specific integrity/security rules and domain agnostic security rules. – Tudor May 22 '14 at 09:27
  • If your security rules do not depend on domain concepts, keep your authorization outside the domain. As an example I see a situation when you allow some actions to a user because this user is assigned a static role: in this case you don't need domain objects state to make the auth decision. If you need to analyze domain state to make a decision (e.g. a customer has reached his purchase limit), put auth inside domain objects. – Pavel S. May 22 '14 at 10:28
  • I was thinking the same, but sometimes is hard to draw a line between technical, application authorization and domain rules that resamble authorization. Also there are alot of opinions regarding authorization that is a cross cutting concern and should be treated as a separate layer using rbac or similar security models. Anyway i also tend to split some rules in the domain and outer layer or try to go with as many auth rules implemented in the domain. Who can : pushButtonForNuclearWar(Person president) in the context of NuclearWar object? – Tudor May 22 '14 at 15:59
0

This is clearly a authorization problem and you want to separate it as such. Let me explain

  • Data is, and should always be, agnostic of business logic.

  • If you can ever have a relationship between a User, Custom and Order then your data store has no business denying the relationship ever.

  • Think of it like this: Data is facts. Today is Thursday and no business executive in the world can change that. If it's decided that on Thursdays we charge 2x as much for our product then our data should not be aware as business rules can change. Changing facts is much harder and only possible in the world of editable media.

  • Source code is version controlled. Data is not, by nature. You don't get to revert your data as a rule.

But, you have legitimate need to limit access to data. Today, 'Joe' is an admin and has access to everything. Tomorrow, he gets a demotion and losses most of his privileges. He is still 'Joe', all customers and orders he created in the past should still be linked to him but he now no longer can see them.

You need an authentication/authorization layer. Once you have proven the user is 'Joe' you need to know what he can access.

This is not for the feint of heart and failure here has been at the core of security issues for decades. There is just now starting to form some real portable architectures and libraries for doing this sort of thing.

Spring security is very powerful but limited to the JVM. You can, however, port their model to whatever platform you liked but it's complicated.

Also have a look at this list of computer security models

So, to be candid on answering your question: Let the domain objects model the potential relationships and apply a security layer.

More practically, find a security layer you can integrate from a trusted provider. Use google OAuth, or OpenID or anything you don't have to implement. You will just do it wrong.

Christian Bongiorno
  • 5,150
  • 3
  • 38
  • 76
  • It's not about doing it wrong :) and I don't trust any cloud service that controls,acts like a man in the middle for my application security,especially when data related to emails or anything else should be managed internally,not by a third party. What does "data" has to do in the case i wrote? It's more about state not data.You need to enforce the domain state...And where else but the domain right?So if an order has as owner a customer with pruchase limit reached, then it's in invalid state. Purchase limit is a business rule that dictates how the other objects perform, not how data is saved. – Tudor May 22 '14 at 18:42
  • Access to a resource and capability of doing something are different things. Access to resource are related to data, and capability of doing something is related to the behaviour of the domain. Like i said in a comment here, authorization seems a bit general term, that's why i'm not sure where and how to draw the line between domain explictit auth rules and domain agnostic auth rules . It's more about design, not about what rules should be implemented, but where should be implemente in which layer. No third party cloud service can provide a deep insight about all the rules an app has. – Tudor May 22 '14 at 18:50
  • Re 1st comment:Explain how you intend to represent 'domain state' as something other than 'data'. If you end up with data that fails a valid business state then you have a bug in your code. That's a whole other discussion. Do you assume the data in your DB is accurate? If not, then you check business state when you load it and if it's wrong... what, shut down the whole system? Fail that transaction? – Christian Bongiorno May 22 '14 at 18:53
  • Re 2nd comment: "Access to a resource" IS doing something (your are accessing it)! What does 'access to a resource' mean if you aren't 'doing' something (like reading it)? – Christian Bongiorno May 22 '14 at 18:55
  • You should not think about the domain as a simple data holder. The domain shows you what the current state is (especially in cqrs) and helps you take decisions how to modify it. You should never persist domain objects in an invalid state, so you cannot have invalid data in the data store. That's why i asked if the domain should do some kind of authorization. – Tudor May 22 '14 at 18:58
  • Well , i am implementing DDD in colaboration with CQRS. I see the read and the writes as different things. The domain model is actually the write model. – Tudor May 22 '14 at 18:59
  • As for "trust a cloud service" -- you must be joking! With respect, you don't understand security at all. Google has NO IDEA what your password is by looking in one of it's DBs. Of course, if you log in they can then capture it. Do you honestly believe you can do a better job of securing your system than google? Assume google is not to be trusted. That means roll your own. And, because you certainly won't do it as well as them you are likely to get hacked. Even in this 'lack of trust' scenario, google is the lesser of 2 evils. Think of all the web sites that let you login with facebook creds. – Christian Bongiorno May 22 '14 at 19:00
  • I was not talking about passwords, i was talking about identifiers that help indentifying if the user is who he claims to be. I was talking about emails, phone numbers, not about passwords. I prefer to keep all my clients data internally. You should read more about data harvesters, and about databases that sell human related informations fetched from twitter, facebook and many other linked networks that are available on the web. Check rap leaf. – Tudor May 22 '14 at 19:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/54229/discussion-between-christian-bongiorno-and-tudor). – Christian Bongiorno May 22 '14 at 19:04
  • P.S. Even stackOverflow may sell information about a user's activity, knowledge. Specially in this case when people that use this network use it for very specific reasons. From another point of view, if stackOverflow/stackexchange is using some type of OpenId solution for other web services , the client who's using SO openId could crawl the user's page and fetch data regarding it's programming activity. That's why I'm not into OpenId and any other type of service that helps in generating a human profile. – Tudor May 22 '14 at 21:28