Search code examples
asp.net-mvcrefactoringdomain-driven-designdata-modelingseparation-of-concerns

Where can I find information on Authentication and Authorization in the context of Domain Driven Design?


I'm trying to do things the DDD (domain driven design) way. And boy do I struggle. In all books I read, Authentication is of no concern and not mentioned!

I've written my own Authentication and Membership Service which are responsible for registering and logging in users, creating salted passwords etc. I do not use .NET's Membership Provider but do rely on Forms Authentication.

I've implemented a User model that holds the Username, E-Mail, PasswordHash, ApprovalStatus etc.

Now I guess the rest of the domain model shouldn't concern itself with the Users. I have a class Person that is used to model Persons and their associated data. As such it can be used to model personal data from users and from non-users. An object of type Company works with Persons, not Users. And an Activity is assigned to a Person, not a User.

The question, how do I relate the Person model to the User model? I don't really want a reference to each other in either of the two models. Should I create some Relationship model called PersonUser and create an additional service that retrieves the person object for the currently authenticated user?


Solution

  • Judging from what you've presented, you've got a couple of known facts:

    1. Every User is a Person
    2. Not every Person is a User

    That being the case, I would expand the person model to include a nullable UserId field so that you can relate the User to the Person for those Persons that are also users.

    Now I'm also going to assume that you have several "Fetch" methods in the person model.. to retrieve a person by ID, Name, Department, etc...

    I would overload (or create a different) fetch method to also retrieve the person object from a User as well (this can be either an id, or the foll user object).

    public IPerson Fetch(IUser user) {}
    

    Of course, since you have the known fact that every user is also a person, I personally see no harm nor foul in expanding the user object to include a person property...

    public interface IUser 
    {
       ...
       IPerson Person { get; set; }
    }
    

    Then, you can return the user object as always.. and perhaps do some funky lazy loading of the person field in the user... or populate both when you fetch the user object.

    I'm not sure if creating a "mapping" table of User <-> Person is going to garner you much of anything beyond what I've outlined above (although you will get kudo's from the hardcore DBA's for denormalizing your data).. to me it's just an extra table to join to to get the same effect.