2011-07-11 21 views
5

Estoy siguiendo el estudio de caso en Patrones de diseño de ASP.NET profesionales por Scott Millet. En el estudio de caso, la autenticación se maneja en el proyecto de infraestructura. Contiene implementaciones como AspFormsAuthentication: IFormsAuthentication, AspMembershipAuthentication: ILocalAuthenticationService.DDD Authentication Service

Esto funciona bien, ya que él está usando el proveedor de membresía incorporado, sin embargo, yo NO, así que necesitaría tener acceso a mis repositorios. En mi caso, ¿no sería mejor colocar mi implementación de ILocalAuthenticationService y AspMembershipAuthentication en el proyecto de Servicios?

me preguntó esto en otro lugar, y alguien respondió:

Me gustaría volver a colocar la funcionalidad para tirar de credenciales en la capa de infraestructura como esta capa se alinea verticalmente con las otras capas horizontales y todas las capas tienen acceso a ella. Como no está utilizando el proveedor de membresía de ASP.NET y puede estar usando algo personalizado que pueda usar credenciales encriptadas, puede usar la capa de infraestructura para ajustar el acceso de esas credenciales y permitir que el repositorio las use cuando sea necesario. Puede hacer que la capa Servicios los obtenga y los pase, pero tiene demasiadas capas para comprender cómo se recuperarán/persistirán los datos y qué acceso de autorización se requiere, lo que no es bueno cuando se intenta crear capas y separar las preocupaciones.

Genial. Esto tiene sentido. Pero no sé a dónde ir desde aquí. El código del estudio de caso:

public class AspMembershipAuthentication : ILocalAuthenticationService 
{ 
    public User Login(string email, string password) 
    { 
     User user = new User(); 
     user.IsAuthenticated= false; 

     if (Membership.ValidateUser(email, password)) 
     { 
      MembershipUser validatedUser = Membership.GetUser(email); 
      user.AuthenticationToken = validatedUser.ProviderUserKey.ToString(); 
      user.Email = email; 
      user.IsAuthenticated = true; 
     } 

     return user; 
    } 

    public User RegisterUser(string email, string password) 
    {    
     MembershipCreateStatus status; 
     User user = new User(); 
     user.IsAuthenticated = false; 

     Membership.CreateUser(email, password, email, 
           Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 
           true, out status); 

     if (status == MembershipCreateStatus.Success) 
     { 
      MembershipUser newlyCreatedUser = Membership.GetUser(email); 
      user.AuthenticationToken = newlyCreatedUser.ProviderUserKey.ToString(); 
      user.Email = email; 
      user.IsAuthenticated = true; 
     } 
     else 
     { 
      switch (status) 
      { 
       case MembershipCreateStatus.DuplicateEmail: 
        throw new InvalidOperationException(
          "There is already a user with this email address."); 
       case MembershipCreateStatus.DuplicateUserName: 
        throw new InvalidOperationException(
          "There is already a user with this email address."); 
       case MembershipCreateStatus.InvalidEmail: 
        throw new InvalidOperationException(
          "Your email address is invalid"); 
       default: 
        throw new InvalidOperationException(
        "There was a problem creating your account. Please try again."); 
      } 
     } 

     return user; 
    }  
} 

Si no estoy usando el proveedor de pertenencia, cómo conecto a la base de datos para comprobar si los partidos de usuario y contraseña, entre otras comprobaciones posibles?

+1

La autenticación es una preocupación de nivel de aplicación. No es parte de tu dominio. – jfar

Respuesta

3

En su capa de infraestructura, cree una clase que implemente ILocalAuthenticationService y realice las llamadas que necesite.

O, si ILocalAuthenticationService es demasiado ASP.NET-y (con sus tipos de devolución de usuario), puede que tenga que transferir su propia variante ILocalAuthenticationService e implementarla.

Luego use su contenedor IoC para resolver ILocalAuthenticationService cuando lo necesite.

+0

Gracias por la respuesta. Mi capa de infraestructura ya tiene ILocalAuthenticationService y, similar a la anterior, la implementación AspMembershipAuthentication. La implementación que publiqué anteriormente usa el proveedor de membresía predeterminado, mientras que no estoy planeando usarlo. Entonces, desde dentro de la capa de Infraestructura, ¿cómo accedería a los datos para realizar esos controles como lo hace la implementación anterior con el Proveedor de Membresía? – getoutofmylaboratory

+0

Veo, ¿entonces su capa de infraestructura no puede ver la capa de datos? ¿Qué pasa si su servicio de autenticación vivió en algún lugar que podría ver el DB? Desde una perspectiva de IoC, a sus clientes realmente no les importa de dónde viene. Si la capa de infraestructura no puede ver DB y su autorización está basada en DB, no puede vivir en la capa de infraestructura, como ya ha averiguado :) – n8wrl

+0

¡Exactamente! Originalmente, estaba planeando hacer esto en la capa de Servicio. Sin embargo, lo cuestioné porque "no es así como se hace en el caso de estudio". Así que pregunté, pero se me recomendó mantenerlo en la capa de Infraestructura debido a la separación de las preocupaciones (de la cita que publiqué). Estaba pensando en ponerlo en la capa de servicio para que pueda usar mis repositorios para poder comunicarme con la base de datos. ¿Qué sugieres basado en eso? – getoutofmylaboratory