authentication - mvc - identity server 4 ejemplos
¿Cómo creo un objeto ClaimsIdentity para Asp.NET MVC 5? (4)
Estoy trabajando en una aplicación .NET MVC 5. No quiero usar Entity Framework. Quiero autenticarme en una base de datos RavenDB. Me parece que quiero reemplazar el UserManager
que viene con el controlador de cuenta. Creo que puedo reescribir todas las funciones de UserManager para que funcionen con mi base de datos, excepto que no entiendo el objeto ClaimsIdentity
.
En el método SignInAsync
, hay una llamada a UserManager.CreateIdentityAsync(...)
. Sé que devuelve un objeto ClaimsIdentity
. Lo que no sé es cómo crear un objeto ClaimsIdentity por mi cuenta.
Veo que tiene 4 propiedades Actor
, BootstrapContext
, Claims
y Label
. No sé para qué se usan estas propiedades, y no sé cómo generarlas correctamente. Supongo que generarlos correctamente es importante ya que es la forma en que se realiza la cookie de autenticación.
Miré la explicación del objeto ClaimsIdentity here , pero eso realmente no me ayudó a entender.
Si pudiera ver el código de CreateIdentityAsync()
, eso probablemente sería útil.
Si estoy haciendo esto mal, por favor avíseme. De lo contrario, si alguien pudiera indicarme cómo generar el objeto ClaimsIdentity, sería útil.
ClaimsIdentity identity = new ClaimsIdentity
{
Actor = ????,
BootstrapContext = ?????,
Claims = ?????,
Label = ?????
}
Creé una implementación RavenDB para la nueva Identidad ASP.NET MVC 5 y la lancé como un paquete NuGet. Esto podría funcionar para ti.
http://www.nuget.org/packages/RavenDB.AspNet.Identity/
Es algo preliminar, pero lo estoy usando en un proyecto real.
Aquí está el proyecto GitHub y un breve hilo sobre el grupo de discusión de RavenDB al respecto.
Creo que "te estás equivocando". ASP.NET Identity Framework está diseñado con persistencia conectable en mente. La forma correcta de sustituir RavenDB por EF es NO reemplazar el UserManager
. Más bien, es implementar una UserStore
reemplazo. Entonces, la línea en el AccountController
que crea el UserManager
cambiará de:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
A:
public AccountController()
: this(new UserManager<ApplicationUser>(new RavenDBUserStore<ApplicationUser>/* connection info here*/)))
Donde RavenDBUserStore
sería una clase, usted escribió que implementó IUserStore
, IUserPasswordStore
y cualquier otra * Store interfaces que necesita para su aplicación en particular.
Este enfoque evita tener que comprender y volver a implementar todo en UserManager
y garantiza que podrá aprovechar las futuras mejoras del UserManager
de MS.
Para obtener más información sobre cómo hacerlo, consulte la Descripción general de proveedores de almacenamiento personalizados para la identidad de ASP.NET y el ejemplo de Implementación de un proveedor personalizado de almacenamiento de identidad ASP.NET de MySQL . También debe consultar el código del paquete RavenDB.AspNet.Identity Nuget creado por David Boike mencionado en su answer . La fuente está en github en https://github.com/ILMServices/RavenDB.AspNet.Identity/tree/master/RavenDB.AspNet.Identity
Esto es lo que se me ocurrió. Me encantaría saber si esta es la forma correcta de lograr esta tarea.
Al trabajar en un sitio web predeterminado de MVC5, fui al Controlador de cuenta y encontré la función SignInAsync()
. Lo ajusté de la siguiente manera:
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
//var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); --> this is where I want to get rid of UserManager
List<Claim> claims = new List<Claim>{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", user.Name), //user.Name from my database
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", user.Id), //user.Id from my database
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "MyApplication"),
new Claim("FirstName", user.FirstName) //user.FirstName from my database
};
ClaimsIdentity identity = new System.Security.Claims.ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
Tenga en cuenta que esto también requiere cambiar la función de [HttpPost] Login
para obtener al usuario de mi base de datos en lugar de usar la función UserManager.FindAsync()
.
Las partes LogIn / LogOff del sitio predeterminado parecen funcionar bien después de estos ajustes. Dejaré esta respuesta aquí por un tiempo antes de aceptarla en caso de que alguien pueda decirme por qué no debería hacerlo de esta manera.
Tal vez el siguiente enlace puede ayudar:
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "Brock"));
claims.Add(new Claim(ClaimTypes.Email, "[email protected]"));
var id = new ClaimsIdentity(claims,DefaultAuthenticationTypes.ApplicationCookie);
var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignIn(id);