7

Ich habe eine ASP.NET MVC 5 Anwendung mit ASP.NET Identity 2.1.0 für die Benutzerauthentifizierung.
In der Vergangenheit hat alles gut funktioniert, aber jetzt habe ich herausgefunden, dass persistente Benutzersitzungen nicht mehr funktionieren. Ich kann nicht sagen, welche Änderung dieser brach, aber es funktionierte, als ich Identität umgesetzt (die Anwendung von SimpleMembership umgewandelt), und dies ist meine Logik, die ich im Moment haben:IsPersistent funktioniert nicht - Cookie ist nur gültig für aktuelle Sitzung

var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, 
            model.RememberMe, shouldLockout: true); 

SignInManager meine ist ApplicationSignInManager basierend auf SignInManager<ApplicationUser, int> und model.RememberMe ist true.

Und mein Setup:

app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 

app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
     LoginPath = new PathString("/Account/Login"), 
     Provider = new CookieAuthenticationProvider 
      { 
       OnValidateIdentity = ApplicationCookieIdentityValidator.OnValidateIdentity(
        validateInterval: TimeSpan.FromMinutes(0), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) 
      } 
    }); 
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); 
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); 
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

Alles funktioniert gut, außer persistierenden die Benutzersitzungen. Ich überprüfte die Cookies, die von meinem Server zurückgegeben wurden, und die .AspNet.ApplicationCookie wird immer als "gültig für aktuelle Sitzung" anstatt eines Datums in der Zukunft zurückgegeben. Wenn ich den Browser schließe und wieder öffne, muss ich mich erneut einloggen ...

Hat jemand eine Idee, warum das nicht funktioniert (mehr)?

PS: ich außer Kraft gesetzt habe SignInAsync in meinem ApplicationSignInManager, weil ich dort einige benutzerdefinierte Logik zu tun, aber ich sogar mit dem Debugger und für den folgenden Aufruf geprüft:

await base.SignInAsync(user, isPersistent, rememberBrowser); 

isPersistent ist true, so ist es schaffen soll ein persistenter Keks.

+0

Ich vermute 'validateInterval: TimeSpan.FromMinutes (0)' kann dies verursachen. Denn bei jeder Anfrage wird das Cookie neu generiert und ein neues gesetzt. Versuchen Sie, 'validateInterval' auf etwas mehr als 0 zu setzen und sehen Sie, ob das funktioniert. – trailmax

+0

@trailmax: Danke, das war es.Änderte sich das mit V 2.1? Weil es am Anfang definitiv funktioniert hat (mit V 2.0). Wie auch immer: Post dies als Antwort und ich werde es akzeptieren. Ich muss jetzt darum herum finden, wie ich (wegen SSO) Validierung für jede Anfrage brauche. – ChrFin

Antwort

6

This is a known bug in Identity und durch Blick auf this answer ist es nicht sehr neu.

Wenn Cookie bei jeder Anfrage neu generiert wird, wird das Flag "IsPersisted" nicht gesetzt, selbst wenn es im ursprünglichen Cookie gesetzt wurde.

Um dies zu umgehen, müssen Sie eine eigene Version des Cookie-Validators implementieren, die das Flag so setzt, wie es sein sollte.

Ich denke, ich habe die Lösung für Sie, aber ich habe es nicht kompiliert oder getestet - nur eine allgemeine Richtung, wo Sie hin müssen. Siehe hierzu gist for full code.
Dies ist nur ein SecurityStampValidator Code aus Decompiler entnommen. Ich habe added lines 91-96. Grundsätzlich nehme ich "IsPersistent" -Flag aus dem vorherigen Cookie und füge es dem neuen Cookie hinzu, wenn es erstellt wird. Das wurde nicht in nicht modifizierter Version gemacht.

Und dann in Ihrem Auth.Config Sie tun:

Provider = new CookieAuthenticationProvider 
      { 
       OnValidateIdentity = MySecurityStampValidator.OnValidateIdentity(
        validateInterval: TimeSpan.FromMinutes(0), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) 
      } 

Beachten Sie jedoch, wenn eine neue Version heraus, prüfen Sie, ob dieses Problem behoben wurde, so dass Sie die schmutzige Fix entfernen können. Dieses Problem ist reported to be fixed, aber kurz nach V2.1 war out.

+1

Vielen Dank. Da ich bereits einen eigenen Validator habe (siehe 'ApplicationCookieIdentityValidator' in meinem Code), musste ich auch nur Ihre Änderungen hinzufügen -> arbeiten! – ChrFin

+0

@ChrFin Ja, mir ist aufgefallen, dass der Name vom Standard abweicht. Froh, dass es hilft! – trailmax

+0

netter Code! Sieht so aus, als ob es fehlt 'mit Microsoft.Owin.Security;', um auf den 'AuthenticationProperties' Typ obwohl – Matthew

1

Die Aktualisierung von AspNet.Identity.Core und AspNet.Identity.Owin auf 2.2.1 sollte dieses Problem beheben.

+1

nach der Aktualisierung hat es immer noch das gleiche Problem und sogar Standard-Vorlage für asp.mvc für Identity-Core hat das gleiche Problem. –

+0

yep, das gleiche Problem mit der Identität Kern ... –

+0

https://stackoverflow.com/questions/31946582/how-ispersistent-works-in-owin-cookie-authentication/46659752#46659752 –