Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which layer should be used for user authentication

I'm tying to use Domain Driven Design in one of my applications and have some question about user authentication.

I have an aggregate root called User which has Value Objects like UserCredentials, Password, ActivationToken, etc. I also have few domain services for managing users. For example UserRegistration service looks like this:

public interface IUserRegistrationService
{
    IEnumerable<string> Register(NewUserRequest request);
}

It checks business rules that are assigned to user registration process and persist user in the database.

Now I want to authenticate user, so I've created UserAuthentication domain service:

public interface UserAuthenticationService
{
    IEnumerable<string> Authenticate(AuthRequest request);
}

It takes user from the repository, checks business rules, updates and persists user data changes like LastLoginDate.

But I have some doubts if authentication process belongs to domain itself or it should belong to application service, as for my domain it doesn't matter how user is authenticated. But on the other hand authentication rules, that are checked inside this service, belong to my domain rules, so they're integral part of my domain.

So where do you put authentication in your DDD based appllications and what is your solution to this issue?

like image 659
Mad Max Avatar asked Sep 18 '25 03:09

Mad Max


2 Answers

1.Generally, authentication and authorization are su-domains in an application. You'd better build an abstraction in application layer/core domain to isolate them.

public interface OrderingService// application layer
{
    void PlaceOder(Order order) {
          //delegate to identity subdomain to validate user request
          UserAuthenticationService.Authenticate(ExtractFrom(order));

          //delegate to booking core domain to handle core business 
          BookingService.placeOrder(order);
    }
}

2.In Identity subdomain, the authentication algorithm could be placed in infrastructure layer:

public class OathUserAuthenticationService:UserAuthenticationService //infrastructure layer
{
    IEnumerable<string> Authenticate(AuthRequest request) {
         ......
    }
}

There are excellent discussion and examples in Implementing Domain Driven Design. The author seperate authentication to an identity subdomain.

like image 161
Yugang Zhou Avatar answered Sep 20 '25 18:09

Yugang Zhou


Following answer is highly depends on my assumptions about your task and environment, so do not beleive me blindly.

I think authentication is a business process. It highly coupled with concepts of User, Registration, UserStatus etc.

If you ask me how to call this business process with the single word, I'd choose UserPolicy. Look at UserPolicy as an aggregate root. It's boundaries includes such entities as: User, RegistrationService, AuthenticationService, UserRepository. All of them must remain consistent. It is easy to achieve, because every action with them is going through their root entity:

IUserPolicy up = container.Resolve<IUserPolicy>();

up.RegisterUser(newUserRequest);

up.AuthUser(authRequest);
like image 28
astef Avatar answered Sep 20 '25 18:09

astef