Many applications make use of user management and user authentication. It is a commonly used and understood aspect, but I think we are doing it wrong.
When you browse the web or read a book you will probably find one of the following 3 domains (or one that is pretty similar).
1. The basic user.
----------
|User |
----------
|username|
|password|
----------
With this user you are able to login and have all user rights in the system. Sometimes a boolean field will be added to indicate if a user is a administrator.
2. The auhoritized user.
----------- -----------
|User | |Authority|
----------- 1 * -----------
|-username|-------------|name |
|-password| -----------
-----------
With this domain users have certain rights based on the referenced authorities.
3. The roles and groups.
---------- ----------- -----------
|User | |Role | |Authority|
---------- 1 * ----------- 1 * -----------
|username|-------------|name |---------|name |
|password| ----------- -----------
----------
With this domain users have roles or are members of groups. For example: 'administrators', 'blog-posters', 'board-member', etc. Those roles each have certain authorities resulting that a user has many authorities through many roles.
I am missing one aspect that I would like to see in this model and that is authentication. Yes I know, there is a username and password but I do not like it.
The status quo of web applications allows users to authenticate themselves with multiple authentication methods (Facebook, OAuth, Twitter, username/password combinations, Google accounts, etc.) and the rigid domains do not support this.
Step 1
To allow one of the above domains to support facebook authentication we can extend the domain like this (the roles and authorities are omitted):
---------- ------------------
|User | |FBAuthentication|
---------- 1 0..1 ------------------
|username|-------------|facebookUserId |
|password| ------------------
----------
I'm still not satisfied because this domain has 2 bad smells:
Step 2
The next step would be to extract the username/password combination from the user model. Lets say you use the Spring Security framework, the domain will look like this:
--------------------- --------- ------------------
|SpringAuthentiction| |User | |FBAuthentication|
--------------------- 0..1 1 --------- 1 0..1 -----------------|
|username |------------| |-----------|facebookUserId |
|password | --------- ------------------
---------------------
This domain will indicate that a user will have zero or many authentications.
Step 3
The last step is to add attributes to the user. These attributes could be a value if the user is enabled or a screen name for the user.
This solution has advantages and disadvantages.
The main disadvantage is a more complex domain and so a more complex application. The main advantage is that a user is able to add multiple authentication methods to its user account. Even more of a singular type.
Another advantage is that this model allows better merging between 2 users. The user for a single authentication can be changed.
Let me hear what you think about this concept and if you can think of reasons why you should or shouldn't adopt it.