J'ai une application qui utilisait FormsAuthentication
, et il y a quelque temps, je l'ai commutée pour utiliser IdentityModel
de WindowsIdentityFramework
afin de pouvoir bénéficier d'une authentification basée sur les revendications, mais elle était plutôt moche à utiliser et à mettre en œuvre. Alors maintenant, je regarde OwinAuthentication
.
Je regarde OwinAuthentication
et le cadre Asp.Net Identity
. Mais la seule implémentation du framework Asp.Net Identity
Pour le moment utilise EntityModel
et j'utilise nHibernate
. Pour l'instant, je cherche à contourner Asp.Net Identity
Et à utiliser directement Owin Authentication
. J'ai finalement pu obtenir une connexion de travail en utilisant les conseils de " Comment puis-je ignorer la magie d'Identity Framework et simplement utiliser le middleware d'authentification OWIN pour obtenir les revendications que je recherche? ", mais maintenant mon cookie contient les revendications sont assez importantes. Lorsque j'ai utilisé le IdentityModel
, j'ai pu utiliser un mécanisme de mise en cache côté serveur qui a mis en cache les revendications sur le serveur et le cookie contenait simplement un jeton simple pour les informations mises en cache. Y a-t-il une fonctionnalité similaire dans OwinAuthentication
, ou devrais-je l'implémenter moi-même?
Je pense que je vais être dans l'un de ces bateaux ...
IdentityModel
dans Owin
que je ne connais pas.Owin
au démarrage de l'application.Je fais tout cela mal et il y a une approche à laquelle je n'ai pas pensé ou j'utilise mal quelque chose dans 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),
});
}
}
[~ # ~] mise à jour [~ # ~] J'ai pu obtenir l'effet souhaité en utilisant les informations fournies par Hongye et j'ai trouvé la logique ci-dessous ...
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);
}
}
Le middleware d'authentification de cookie OWIN ne prend pas encore en charge la fonctionnalité de mise en cache de session. # 2 n'est pas une option.
# 3 est la bonne voie à suivre. Comme Prabu l'a suggéré, vous devriez faire ce qui suit dans votre code:
OnResponseSignIn:
OnValidateIdentity:
J'allais vous suggérer de compresser le cookie, mais j'ai trouvé que OWIN l'avait déjà fait dans son TicketSerializer. Pas une option pour vous.
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.
}
}
Vous pouvez implémenter IAuthenticationSessionStore pour stocker les cookies dans la base de données.
Voici un exemple de stockage de cookie dans redis.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
SessionStore = new RedisSessionStore(new TicketDataFormat(dataProtector)),
LoginPath = new PathString("/Auth/LogOn"),
LogoutPath = new PathString("/Auth/LogOut"),
});
Consultez l'exemple complet ici