asp.net - claim - owin authentication web api
El lado del servidor reclama el almacenamiento en caché con Owin Authentication (3)
El middleware de autenticación de cookies OWIN aún no admite caché de sesión como característica. # 2 no es una opción.
# 3 es el camino correcto a seguir. Como sugirió Prabu, debes hacer lo siguiente en tu código:
OnResponseSignIn:
- Guardar contexto.Identidad en la memoria caché con una clave única (GUID)
- Crear un nuevo ClaimsIdentity incrustado con la clave única
- Reemplazar contexto.Identidad con la nueva identidad
OnValidateIdentity:
- Obtenga el reclamo clave único del contexto. Identidad
- Obtenga la identidad almacenada en caché mediante la clave única
- Llamar context.ReplaceIdentity con la identidad en caché
Iba a sugerirle que descomprima la cookie, pero descubrí que OWIN ya lo hizo en su TicketSerializer. No es una opción para ti.
Tengo una aplicación que solía usar FormsAuthentication
, y hace un tiempo lo FormsAuthentication
para usar el IdentityModel
de WindowsIdentityFramework
para poder beneficiarme de la autenticación basada en notificaciones, pero era bastante feo de usar e implementar. Así que ahora estoy viendo OwinAuthentication
.
Estoy mirando OwinAuthentication
y el marco de Asp.Net Identity
. Pero la única implementación del framework Asp.Net Identity
en este momento usa EntityModel
y estoy usando nHibernate
. Así que, por el momento, intento intentar eludir Asp.Net Identity
y utilizar la Owin Authentication
directamente. Finalmente pude obtener un inicio de sesión funcional usando los consejos de " ¿Cómo ignoro la magia de Identity Framework y simplemente uso el middleware de autenticación de OWIN para obtener los reclamos que busco? ", Pero ahora mi cookie que contiene los reclamos es bastante grande. Cuando utilicé IdentityModel
, pude usar un mecanismo de caché del lado del servidor que almacenaba en caché los reclamos en el servidor y la cookie solo contenía un token simple para la información en caché. ¿Hay alguna característica similar en OwinAuthentication
, o tendré que implementarla yo mismo?
Espero estar en uno de estos barcos ...
- La cookie permanece como 3 KB, bueno, es un poco grande.
- Habilite una característica similar a SessionCaching de
Owin
enOwin
que no conozco. - Escribir mi propia implementación para almacenar en caché la información que hace que la cookie se hinche y ver si puedo conectarla cuando configuro
Owin
al inicio de la aplicación. Estoy haciendo todo mal y hay un enfoque en el que no había pensado o mal uso de algo en
Owin
.public class OwinConfiguration { public void Configuration(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Application", AuthenticationMode = AuthenticationMode.Active, CookieHttpOnly = true, CookieName = "Application", ExpireTimeSpan = TimeSpan.FromMinutes(30), LoginPath = "/Login", LogoutPath = "/Logout", ReturnUrlParameter="ReturnUrl", SlidingExpiration = true, Provider = new CookieAuthenticationProvider() { OnValidateIdentity = async context => { //handle custom caching here?? } } //CookieName = CookieAuthenticationDefaults.CookiePrefix + ExternalAuthentication.ExternalCookieName, //ExpireTimeSpan = TimeSpan.FromMinutes(5), }); } }
ACTUALIZACIÓN Pude obtener el efecto deseado utilizando la información proporcionada por Hongye y presenté la siguiente lógica ...
Provider = new CookieAuthenticationProvider()
{
OnValidateIdentity = async context =>
{
var userId = context.Identity.GetUserId(); //Just a simple extension method to get the ID using identity.FindFirst(x => x.Type == ClaimTypes.NameIdentifier) and account for possible NULLs
if (userId == null) return;
var cacheKey = "MyApplication_Claim_Roles_" + userId.ToString();
var cachedClaims = System.Web.HttpContext.Current.Cache[cacheKey] as IEnumerable<Claim>;
if (cachedClaims == null)
{
var securityService = DependencyResolver.Current.GetService<ISecurityService>(); //My own service to get the user''s roles from the database
cachedClaims = securityService.GetRoles(context.Identity.Name).Select(role => new Claim(ClaimTypes.Role, role.RoleName));
System.Web.HttpContext.Current.Cache[cacheKey] = cachedClaims;
}
context.Identity.AddClaims(cachedClaims);
}
}
Puede implementar IAuthenticationSessionStore para almacenar cookies en la base de datos.
Aquí hay un ejemplo para almacenar cookies en redis.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
SessionStore = new RedisSessionStore(new TicketDataFormat(dataProtector)),
LoginPath = new PathString("/Auth/LogOn"),
LogoutPath = new PathString("/Auth/LogOut"),
});
Mira el ejemplo completo aquí
Provider = new CookieAuthenticationProvider()
{
OnResponseSignIn = async context =>
{
// This is the last chance before the ClaimsIdentity get serialized into a cookie.
// You can modify the ClaimsIdentity here and create the mapping here.
// This event is invoked one time on sign in.
},
OnValidateIdentity = async context =>
{
// This method gets invoked for every request after the cookie is converted
// into a ClaimsIdentity. Here you can look up your claims from the mapping table.
}
}