2016-11-16 26 views
5

Czy mogę użyć MemoryCache w urządzeniu ITicketStore do zapisania AuthenticationTicket?Uwierzytelnianie plików cookie Asp.Net Core

Tło: Moja aplikacja internetowa korzysta z uwierzytelniania Cookie:

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true, 
    LoginPath = new PathString("/Authentication/SignIn"), 
    LogoutPath = new PathString("/Authentication/SignOut"), 
    ReturnUrlParameter = "/Authentication/SignIn" 
}); 

My Web API obsługuje proces autoryzacji przy użyciu tokenów dostępu (OAuth2).

Czasami (w niektórych przeglądarek) dodaje się wyjątek:

nieobsługiwany wyjątek: spowodował pakietowego ciastko jest niekompletny. Znaleziono tylko 1 z oczekiwanych 2 fragmentów, w sumie 4021 znaków. Limit rozmiaru klienta mógł zostać przekroczony.

Ciastko jest oczywiście za duże. To dziwne, ponieważ nie używam wielu roszczeń. Wszystkie są domyślnymi roszczeniami (nameidentifier, nonce, exp, etc.). Próbuję teraz wdrożyć własne ITicketStore jako SessionStore na CookieAuthenticationOptions. Numer AuthenticationTicket zostanie zapisany w postaci MemoryCache (podobnie jak w tym sample). Jestem bardzo nowy w tym temacie i nie jestem pewien, czy jest to dobre podejście i czy MemoryCache jest prawidłowym rozwiązaniem.

+0

https://github.com/aspnet/Security/issues/830 Ten problem może być github pomocny dla ciebie. –

Odpowiedz

6

mogę używać MemoryCache w ITicketStore do przechowywania AuthenticationTicket?

Oczywiście, jest to implementacja, z której korzystam od prawie roku.

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AuthenticationScheme = "App.Cookie", 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true, 
    LoginPath = new PathString("/Authentication/SignIn"), 
    LogoutPath = new PathString("/Authentication/SignOut"), 
    ReturnUrlParameter = "/Authentication/SignIn", 
    SessionStore = new MemoryCacheStore(cache) 
}); 

Realizacja MemoryCacheStore wygląda tak, a następnie the example że wspólna:

public class MemoryCacheStore : ITicketStore 
{ 
    private const string KeyPrefix = "AuthSessionStore-; 
    private readonly IMemoryCache _cache; 

    public MemoryCacheStore(IMemoryCache cache) 
    { 
     _cache = cache; 
    } 

    public async Task<string> StoreAsync(AuthenticationTicket ticket) 
    { 
     var key = KeyPrefix + Guid.NewGuid(); 
     await RenewAsync(key, ticket); 
     return key; 
    } 

    public Task RenewAsync(string key, AuthenticationTicket ticket) 
    { 
     // https://github.com/aspnet/Caching/issues/221 
     // Set to "NeverRemove" to prevent undesired evictions from gen2 GC 
     var options = new MemoryCacheEntryOptions 
     { 
      Priority = CacheItemPriority.NeverRemove 
     }; 
     var expiresUtc = ticket.Properties.ExpiresUtc; 

     if (expiresUtc.HasValue) 
     { 
      options.SetAbsoluteExpiration(expiresUtc.Value); 
     }  

     options.SetSlidingExpiration(TimeSpan.FromMinutes(60)); 

     _cache.Set(key, ticket, options); 

     return Task.FromResult(0); 
    } 

    public Task<AuthenticationTicket> RetrieveAsync(string key) 
    { 
     AuthenticationTicket ticket; 
     _cache.TryGetValue(key, out ticket); 
     return Task.FromResult(ticket); 
    } 

    public Task RemoveAsync(string key) 
    { 
     _cache.Remove(key); 
     return Task.FromResult(0); 
    } 
} 
+0

Dzięki za odpowiedź. Czy to podejście ma jakiekolwiek wady w porównaniu do używania plików cookie? W aplikacji internetowej może zabraknąć pamięci to jedyna rzecz, jaką mogę wymyślić. – jasdefer

+0

W rzeczywistości używa plików cookie, stąd "UseCookieAuthentication". Jeśli pamięć jest problemem, należy rozważyć fakt, że wygasają one i spadną z pamięci po jej wygaśnięciu, ponieważ zostaną one zwolnione i wyczyszczone. Ponadto są one małe ... podobnie, w zależności od konfiguracji hosta aplikacja może określić, czy kiedykolwiek będzie miała wpływ. Chciałbyś móc skalować. –

+0

Brak pamięci nie jest tak naprawdę problemem. Właśnie myślałem o ogólnych wadach. Tak, używa ciasteczek, ale sam "AuthenticationTicket" nie jest przechowywany w ciasteczku, tylko referencja. Czy to jest poprawne? – jasdefer