Sí - muy buena pregunta. Al igual que @Andrew Cooper, nuestro equipo también pasó por todo esto.
Fuimos con los siguientes enfoques (correcto o incorrecto):
suscripciones personalizado Proveedor
Ni yo u otro desarrollador son fans de la incorporada en el proveedor de pertenencia ASP.NET . Está demasiado saturado para lo que trata nuestro sitio (simple, sitio web social impulsado por UGC). Creamos uno muy simple que hace lo que nuestra aplicación necesita, y nada más. Mientras que el proveedor de membresía incorporado hace todo lo que podría necesitar, pero lo más probable es que no lo haga.
formularios personalizados de autenticación de entradas/Autenticación
Todo en nuestra aplicación utiliza la inyección de dependencias interfaz impulsada (StructureMap). Esto incluye la Autenticación de formularios. Creamos una interfaz muy delgada:
public interface IAuthenticationService
{
void SignIn(User user, HttpResponseBase httpResponseBase);
void SignOut();
}
Esta interfaz simple permite simulaciones/pruebas fáciles. Con la implementación, creamos un ticket de autenticación de formularios personalizado que contiene: elementos como UserId y Roles, que se requieren en cada solicitud de HTTP, no cambian con frecuencia y, por lo tanto, no se deben buscar en cada solicitud.
A continuación, utilizamos un filtro de acción para descifrar el ticket de autenticación de formularios (incluidas las funciones) y lo pegamos en el HttpContext.Current.User.Identity
(para el cual nuestro objeto Principal también está basado en interfaz).
El uso de [Autorizar] y [AdminOnly]
Todavía pueden hacer uso de la autorización en los atributos MVC. Y también creamos uno para cada función. [AdminOnly]
simplemente comprueba el rol para el usuario actual y arroja un 401 (prohibido).
simple, mesa única para el usuario, sencilla POCO
Toda la información de usuario se almacena en una sola tabla (con la excepción de la información "opcional" del usuario, tales como los intereses del perfil). Esto se asigna a un POCO (Entity Framework) simple, que también tiene una lógica de dominio incorporada en el objeto.
Repositorio de usuario/servicio
simple repositorio de usuario que es dominio específico. Cosas como cambiar la contraseña, actualizar el perfil, recuperar usuarios, etc. El repositorio llama a la lógica de dominio en el objeto Usuario que mencioné anteriormente. El servicio es una envoltura delgada en la parte superior del repositorio, que separa los métodos de repositorio individuales (por ejemplo, Buscar) en otros más especializados (FindById, FindByNickname).
dominio separado de la seguridad
Nuestro "dominio" del usuario y su/información de su asociación. Esto incluye el nombre, perfil, facebook/integración social, etc.
Cosas como "Login", "Salir" se trata de la autenticación y cosas como "ofertas User.IsInRole" con la autorización y por lo tanto no pertenecen en el dominio.
Así que nuestros controladores funcionan tanto con IAuthenticationService
como con IUserService
.
La creación de un perfil es un ejemplo perfecto de lógica de dominio, que también se combina con la lógica de autenticación.
Esto es lo que nuestros de las miradas como:
[HttpPost]
[ActionName("Signup")]
public ActionResult Signup(SignupViewModel model)
{
if (ModelState.IsValid)
{
try
{
// Map to Domain Model.
var user = Mapper.Map<SignupViewModel, Core.Entities.Users.User>(model);
// Create salt and hash password.
user.Password = _authenticationService.SaltAndHashPassword();
// Signup User.
_userService.Save(user);
// Save Changes.
_unitOfWork.Commit();
// Forms Authenticate this user.
_authenticationService.SignIn(user, Response);
// Redirect to homepage.
return RedirectToAction("Index", "Home", new { area = "" });
}
catch (Exception exception)
{
ModelState.AddModelError("SignupError", "Sorry, an error occured during Signup. Please try again later.");
_loggingService.Error(exception);
}
}
return View(model);
}
Resumen
Lo anterior ha funcionado bien para nosotros. I me encanta tener una tabla de usuario simple, y no esa locura hinchada que es el proveedor de membresía de ASP.NET. Es simple y representa nuestro dominio , no la representación de ASP.NET de él.
Dicho esto, como he dicho, tenemos un sitio web simple. Si está trabajando en un sitio web bancario, tendría cuidado de reinventar la rueda.
Mi consejo para usar es crear su dominio/modelo primero, antes de siquiera pensar en la autenticación. (por supuesto, esto es de lo que se trata DDD).
Luego, determine sus requisitos de seguridad y elija un proveedor de autenticación (comercial o personalizado) de forma adecuada.
No deje que ASP.NET dicte cómo debe diseñarse su dominio. Esta es la trampa en la que la mayoría de la gente cae (incluido yo, en un proyecto anterior).
¡Buena suerte!
Buena pregunta, y estoy ansioso por ver respuestas decentes. Abordé el mismo tema en un proyecto hace aproximadamente 4 meses, y no estoy seguro de que esté contento con el enfoque que terminé tomando. –
Hubiera votado esta pregunta, pero realmente es como 10 preguntas en una. El mejor método para hacer preguntas específicas con respuesta es simplemente comenzar a crear prototipos, y decidir si vale la pena el esfuerzo de aprender cada uno de estos sistemas en lugar de escribirlos usted mismo. Ninguno es muy difícil, y probablemente debas dejar que tus objetivos guíen tus decisiones. –
relacionado: http://stackoverflow.com/questions/3964989/how-to-pass-current-user-information-to-all-layers-in-ddd/3969014#3969014 –