asp.net - UseCookieAuthentication with Distributed Cache Ticket Store removing cache entries before set timetout -
i have asp.net core application configuring cookie authentication , openid connect authentication. using session , distributed sql server cache.
in cookie authentication configuration, setting sessionstore property use distributed cache ticket store. have session timeout set 60 minutes. when put items session directly, uses sql cache , entries show 60 minute sliding expire time. works fine. now, when cookie auth uses distributed cache ticket store, can see entries in database (with sliding 60 minute timeout). if let web page sit 20 minutes or more , refresh page, ticket store removes cache entry in database cookie; though full 60 minutes have not passed. when debugging ticket store, see call retrieve called, call remove, , call retrieve; @ point there no more cache entry.
i'm sure i'm missing setting somewhere, cookie cache entries being cleaned , removed prematurely. cannot figure out why.
here relevant parts of startup:
public class startup { // ... public void configureservices(iservicecollection services) { // app insights services.addapplicationinsightstelemetry(this.configuration); // authentication services.addauthentication(options => options.signinscheme = cookieauthenticationdefaults.authenticationscheme); // options services.addoptions() .configure<configurationoptions>(this.configuration) .addutilitieslayerconfigurationoptions(this.configuration) .adddatalayerconfigurationoptions(this.configuration) .addserviceslayerconfigurationoptions(this.configuration) .addwebapplayerconfigurationoptions(this.configuration); // caching/session services.adddistributedsqlservercache(this.configuresqlservercacheoptions); services.addsession(this.configuresessionoptions); // mvc services.addmvc(configuremvcoptions); // custom services services .addconfigurationlayerservices() .addcommonlayerservices() .addutilitieslayerservices() .addserviceslayerservices(this.configuration); } public void configure( iapplicationbuilder app, ihostingenvironment env, iserviceprovider serviceprovider, iloggerfactory loggerfactory, iticketstore distributedcacheticketstore) { // setup logging loggerfactory.adddebug(); // app insights request telemetry (this must first) app.useapplicationinsightsrequesttelemetry(); // exceptions if (env.isdevelopment()) { app.usedeveloperexceptionpage(new developerexceptionpageoptions { sourcecodelinecount = 10 }); } else { app.useexceptionhandler("/error"); } // app insights exception telemetry (right after exception config) app.useapplicationinsightsexceptiontelemetry(); // session app.usesession(); // status code pages (redirect error controller) app.usestatuscodepageswithredirects("/error/{0}"); // static files // before auth, no static files require auth // if wanth auth static files, move after auth middleware app.usestaticfiles(); // auth app.usecookieauthentication(this.buildcookieauthenticationoptions(distributedcacheticketstore)); app.useopenidconnectauthentication(this.buildopenidconnectoptions()); // mvc app.usemvc(); } private cookieauthenticationoptions buildcookieauthenticationoptions(iticketstore ticketstore) { var configuration = new configurationoptions(); this.configuration.bind(configuration); return new cookieauthenticationoptions { cookiesecure = cookiesecurepolicy.sameasrequest, cookiename = configuration.session.authenticationcookiename, accessdeniedpath = "/access-denied", sessionstore = ticketstore }; } private openidconnectoptions buildopenidconnectoptions() { var configuration = new configurationoptions(); this.configuration.bind(configuration); return new openidconnectoptions { clientid = configuration.azureactivedirectory.clientid, authority = configuration.azureactivedirectory.authority, postlogoutredirecturi = configuration.azureactivedirectory.postlogoutredirecturi, responsetype = openidconnectresponsetype.codeidtoken, events = new openidconnectevents { onredirecttoidentityprovider = this.onredirecttoidentityprovider, onremotefailure = this.onremotefailure, ontokenvalidated = this.ontokenvalidated, onauthorizationcodereceived = this.onauthorizationcodereceived, onauthenticationfailed = this.onauthenticationfailed } }; } }
here distributedcacheticketstore:
public class distributedcacheticketstore : iticketstore { private readonly distributedcacheticketstoreoptions options; private readonly idistributedcache distributedcache; private readonly idataprotector dataprotector; private readonly ilogger<distributedcacheticketstore> logger; public distributedcacheticketstore( ioptions<distributedcacheticketstoreoptions> optionsaccessor, idistributedcache distributedcache, idataprotectionprovider dataprotectionprovider, ilogger<distributedcacheticketstore> logger) { this.options = optionsaccessor.value; this.distributedcache = distributedcache; this.dataprotector = dataprotectionprovider.createprotector(this.gettype().fullname); this.logger = logger; } public async task<string> storeasync(authenticationticket ticket) { var key = guid.newguid().tostring(); var ticketbytes = this.dataprotector.protect(ticketserializer.default.serialize(ticket)); await this.distributedcache.setasync(key, ticketbytes, new distributedcacheentryoptions { slidingexpiration = timespan.fromminutes(this.options.session.timeoutminutes) }); this.logger.authenticationticketstoredincache(key); return key; } public async task renewasync(string key, authenticationticket ticket) { var ticketbytes = this.dataprotector.protect(ticketserializer.default.serialize(ticket)); await this.distributedcache.setasync(key, ticketbytes, new distributedcacheentryoptions { slidingexpiration = timespan.fromminutes(this.options.session.timeoutminutes) }); this.logger.authenticationticketrenewedincache(key); } public async task<authenticationticket> retrieveasync(string key) { var ticketbytes = await this.distributedcache.getasync(key); var ticket = ticketserializer.default.deserialize(this.dataprotector.unprotect(ticketbytes)); this.logger.authenticationticketretrievedfromcache(key); return ticket; } public async task removeasync(string key) { var ticketbytes = await this.distributedcache.getstringasync(key); if (ticketbytes != null) { await this.distributedcache.removeasync(key); this.logger.authenticationticketremovedfromcache(key); } } }
Comments
Post a Comment