How to create a persistent ticket in Redis
I have an Identity server 4 application which i am trying to get to remember (persist) the user login.
I think i have tracked the issue down to something in Redis.
When the tickets are stored in redis they are stored with a time out on them.
127.0.0.1:6379> ttl Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 3014
As long as the application is open redis will refresh the time out.
1542808250.760394 [0 lua] "EXPIRE" "Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd" "3600"
This is fine as long as the user is active on the application they key continues to be refreshed. However if the user goes home and comes back the next day their application is no longer logged in.
I was able to fix this by manually logging in to redis and setting the key to Persist
127.0.0.1:6379> Persist XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 1
127.0.0.1:6379> ttl XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) -1
I think the issue is how the keys are created in redis.
RedisCacheTicketStore
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace Xena.IdentityServer.Services
{
public class RedisCacheTicketStore : ITicketStore
{
private readonly ILogger _logger;
private string KeyPrefix = "AuthSessionStore-";
private IDistributedCache _cache;
public RedisCacheTicketStore(RedisCacheOptions options, ILogger logger, IConfiguration config)
{
KeyPrefix = config["Redis:ApplicationName"] + "-";
_logger = logger;
_cache = new RedisCache(options);
}
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var guid = Guid.NewGuid();
var key = KeyPrefix + guid.ToString();
await RenewAsync(key, ticket);
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method StoreAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
options.SetSlidingExpiration(TimeSpan.FromMinutes(60));
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RenewAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
AuthenticationTicket ticket;
byte bytes = null;
bytes = _cache.Get(key);
ticket = DeserializeFromBytes(bytes, _logger);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RetrieveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(ticket);
}
public Task RemoveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
_cache.Remove(key);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RemoveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
private static byte SerializeToBytes(AuthenticationTicket source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var ticket = TicketSerializer.Default.Serialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method SerializeToBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return ticket;
}
private static AuthenticationTicket DeserializeFromBytes(byte source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var hold = source == null ? null : TicketSerializer.Default.Deserialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method DeserializeFromBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return hold;
}
}
}
I can go though the code and see that the AuthenticationTicket is set to isPersistant when going though the StoreAsync method. However it doesnt create a persistent ticket it still has a time out on it.
How do i tell _cache.Set(key, val, options); to set a persistent ticket and not one with a timeout?
c# asp.net-core redis identityserver4
add a comment |
I have an Identity server 4 application which i am trying to get to remember (persist) the user login.
I think i have tracked the issue down to something in Redis.
When the tickets are stored in redis they are stored with a time out on them.
127.0.0.1:6379> ttl Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 3014
As long as the application is open redis will refresh the time out.
1542808250.760394 [0 lua] "EXPIRE" "Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd" "3600"
This is fine as long as the user is active on the application they key continues to be refreshed. However if the user goes home and comes back the next day their application is no longer logged in.
I was able to fix this by manually logging in to redis and setting the key to Persist
127.0.0.1:6379> Persist XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 1
127.0.0.1:6379> ttl XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) -1
I think the issue is how the keys are created in redis.
RedisCacheTicketStore
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace Xena.IdentityServer.Services
{
public class RedisCacheTicketStore : ITicketStore
{
private readonly ILogger _logger;
private string KeyPrefix = "AuthSessionStore-";
private IDistributedCache _cache;
public RedisCacheTicketStore(RedisCacheOptions options, ILogger logger, IConfiguration config)
{
KeyPrefix = config["Redis:ApplicationName"] + "-";
_logger = logger;
_cache = new RedisCache(options);
}
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var guid = Guid.NewGuid();
var key = KeyPrefix + guid.ToString();
await RenewAsync(key, ticket);
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method StoreAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
options.SetSlidingExpiration(TimeSpan.FromMinutes(60));
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RenewAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
AuthenticationTicket ticket;
byte bytes = null;
bytes = _cache.Get(key);
ticket = DeserializeFromBytes(bytes, _logger);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RetrieveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(ticket);
}
public Task RemoveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
_cache.Remove(key);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RemoveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
private static byte SerializeToBytes(AuthenticationTicket source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var ticket = TicketSerializer.Default.Serialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method SerializeToBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return ticket;
}
private static AuthenticationTicket DeserializeFromBytes(byte source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var hold = source == null ? null : TicketSerializer.Default.Deserialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method DeserializeFromBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return hold;
}
}
}
I can go though the code and see that the AuthenticationTicket is set to isPersistant when going though the StoreAsync method. However it doesnt create a persistent ticket it still has a time out on it.
How do i tell _cache.Set(key, val, options); to set a persistent ticket and not one with a timeout?
c# asp.net-core redis identityserver4
Because yourticket.ExpiresUtc
has a value, you're callingoptions.SetAbsoluteExpiration(...)
- you're not checking whetherticket.IsPersistent
istrue
before doing this. Can't you just skip the calls tooptions.SetAbsoluteExpiration(...)
andoptions.SetSlidingExpiration(...)
whenticket.IsPersistent
istrue
?
– Kirk Larkin
Nov 21 '18 at 14:23
If I dont set a sliding it grabs a number from the ExpiresUtc so i end up with a time out of 1209548 which is good. However will it continue to slide if the user logs in? I am still testing this.
– DaImTo
Nov 21 '18 at 14:34
add a comment |
I have an Identity server 4 application which i am trying to get to remember (persist) the user login.
I think i have tracked the issue down to something in Redis.
When the tickets are stored in redis they are stored with a time out on them.
127.0.0.1:6379> ttl Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 3014
As long as the application is open redis will refresh the time out.
1542808250.760394 [0 lua] "EXPIRE" "Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd" "3600"
This is fine as long as the user is active on the application they key continues to be refreshed. However if the user goes home and comes back the next day their application is no longer logged in.
I was able to fix this by manually logging in to redis and setting the key to Persist
127.0.0.1:6379> Persist XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 1
127.0.0.1:6379> ttl XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) -1
I think the issue is how the keys are created in redis.
RedisCacheTicketStore
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace Xena.IdentityServer.Services
{
public class RedisCacheTicketStore : ITicketStore
{
private readonly ILogger _logger;
private string KeyPrefix = "AuthSessionStore-";
private IDistributedCache _cache;
public RedisCacheTicketStore(RedisCacheOptions options, ILogger logger, IConfiguration config)
{
KeyPrefix = config["Redis:ApplicationName"] + "-";
_logger = logger;
_cache = new RedisCache(options);
}
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var guid = Guid.NewGuid();
var key = KeyPrefix + guid.ToString();
await RenewAsync(key, ticket);
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method StoreAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
options.SetSlidingExpiration(TimeSpan.FromMinutes(60));
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RenewAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
AuthenticationTicket ticket;
byte bytes = null;
bytes = _cache.Get(key);
ticket = DeserializeFromBytes(bytes, _logger);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RetrieveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(ticket);
}
public Task RemoveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
_cache.Remove(key);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RemoveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
private static byte SerializeToBytes(AuthenticationTicket source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var ticket = TicketSerializer.Default.Serialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method SerializeToBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return ticket;
}
private static AuthenticationTicket DeserializeFromBytes(byte source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var hold = source == null ? null : TicketSerializer.Default.Deserialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method DeserializeFromBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return hold;
}
}
}
I can go though the code and see that the AuthenticationTicket is set to isPersistant when going though the StoreAsync method. However it doesnt create a persistent ticket it still has a time out on it.
How do i tell _cache.Set(key, val, options); to set a persistent ticket and not one with a timeout?
c# asp.net-core redis identityserver4
I have an Identity server 4 application which i am trying to get to remember (persist) the user login.
I think i have tracked the issue down to something in Redis.
When the tickets are stored in redis they are stored with a time out on them.
127.0.0.1:6379> ttl Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 3014
As long as the application is open redis will refresh the time out.
1542808250.760394 [0 lua] "EXPIRE" "Ids-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd" "3600"
This is fine as long as the user is active on the application they key continues to be refreshed. However if the user goes home and comes back the next day their application is no longer logged in.
I was able to fix this by manually logging in to redis and setting the key to Persist
127.0.0.1:6379> Persist XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) 1
127.0.0.1:6379> ttl XenaIdentityserver-v2-Local-Key-74c112d5-e0f4-48c4-9d0f-cd8e62f12dfd
(integer) -1
I think the issue is how the keys are created in redis.
RedisCacheTicketStore
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace Xena.IdentityServer.Services
{
public class RedisCacheTicketStore : ITicketStore
{
private readonly ILogger _logger;
private string KeyPrefix = "AuthSessionStore-";
private IDistributedCache _cache;
public RedisCacheTicketStore(RedisCacheOptions options, ILogger logger, IConfiguration config)
{
KeyPrefix = config["Redis:ApplicationName"] + "-";
_logger = logger;
_cache = new RedisCache(options);
}
public async Task<string> StoreAsync(AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var guid = Guid.NewGuid();
var key = KeyPrefix + guid.ToString();
await RenewAsync(key, ticket);
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method StoreAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return key;
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var sw = new Stopwatch();
sw.Start();
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
{
options.SetAbsoluteExpiration(expiresUtc.Value);
}
options.SetSlidingExpiration(TimeSpan.FromMinutes(60));
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RenewAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
AuthenticationTicket ticket;
byte bytes = null;
bytes = _cache.Get(key);
ticket = DeserializeFromBytes(bytes, _logger);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RetrieveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(ticket);
}
public Task RemoveAsync(string key)
{
var sw = new Stopwatch();
sw.Start();
_cache.Remove(key);
sw.Stop();
_logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method RemoveAsync Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return Task.FromResult(0);
}
private static byte SerializeToBytes(AuthenticationTicket source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var ticket = TicketSerializer.Default.Serialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method SerializeToBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return ticket;
}
private static AuthenticationTicket DeserializeFromBytes(byte source, ILogger logger)
{
var sw = new Stopwatch();
sw.Start();
var hold = source == null ? null : TicketSerializer.Default.Deserialize(source);
sw.Stop();
logger.LogDebug(LoggingEvents.RedisCacheTicketStore, "Redis Method DeserializeFromBytes Elapsed {sw.ElapsedMilliseconds}", sw.ElapsedMilliseconds);
return hold;
}
}
}
I can go though the code and see that the AuthenticationTicket is set to isPersistant when going though the StoreAsync method. However it doesnt create a persistent ticket it still has a time out on it.
How do i tell _cache.Set(key, val, options); to set a persistent ticket and not one with a timeout?
c# asp.net-core redis identityserver4
c# asp.net-core redis identityserver4
asked Nov 21 '18 at 14:06
DaImToDaImTo
43.3k1058236
43.3k1058236
Because yourticket.ExpiresUtc
has a value, you're callingoptions.SetAbsoluteExpiration(...)
- you're not checking whetherticket.IsPersistent
istrue
before doing this. Can't you just skip the calls tooptions.SetAbsoluteExpiration(...)
andoptions.SetSlidingExpiration(...)
whenticket.IsPersistent
istrue
?
– Kirk Larkin
Nov 21 '18 at 14:23
If I dont set a sliding it grabs a number from the ExpiresUtc so i end up with a time out of 1209548 which is good. However will it continue to slide if the user logs in? I am still testing this.
– DaImTo
Nov 21 '18 at 14:34
add a comment |
Because yourticket.ExpiresUtc
has a value, you're callingoptions.SetAbsoluteExpiration(...)
- you're not checking whetherticket.IsPersistent
istrue
before doing this. Can't you just skip the calls tooptions.SetAbsoluteExpiration(...)
andoptions.SetSlidingExpiration(...)
whenticket.IsPersistent
istrue
?
– Kirk Larkin
Nov 21 '18 at 14:23
If I dont set a sliding it grabs a number from the ExpiresUtc so i end up with a time out of 1209548 which is good. However will it continue to slide if the user logs in? I am still testing this.
– DaImTo
Nov 21 '18 at 14:34
Because your
ticket.ExpiresUtc
has a value, you're callingoptions.SetAbsoluteExpiration(...)
- you're not checking whether ticket.IsPersistent
is true
before doing this. Can't you just skip the calls to options.SetAbsoluteExpiration(...)
and options.SetSlidingExpiration(...)
when ticket.IsPersistent
is true
?– Kirk Larkin
Nov 21 '18 at 14:23
Because your
ticket.ExpiresUtc
has a value, you're callingoptions.SetAbsoluteExpiration(...)
- you're not checking whether ticket.IsPersistent
is true
before doing this. Can't you just skip the calls to options.SetAbsoluteExpiration(...)
and options.SetSlidingExpiration(...)
when ticket.IsPersistent
is true
?– Kirk Larkin
Nov 21 '18 at 14:23
If I dont set a sliding it grabs a number from the ExpiresUtc so i end up with a time out of 1209548 which is good. However will it continue to slide if the user logs in? I am still testing this.
– DaImTo
Nov 21 '18 at 14:34
If I dont set a sliding it grabs a number from the ExpiresUtc so i end up with a time out of 1209548 which is good. However will it continue to slide if the user logs in? I am still testing this.
– DaImTo
Nov 21 '18 at 14:34
add a comment |
1 Answer
1
active
oldest
votes
After tip from Kirk Larkin in a comment. It occurred to me that all i really needed to do was set the timeout longer then it would continue to slide it as long as the user was active. If i had set it to Persist then it would have been in redis forever and thats really not what we want. We want it in there for a given period of time as long as the user comes back from time to time they will continue to appear to be logged in.
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
options.SetAbsoluteExpiration(expiresUtc.Value);
if (ticket.Properties.IsPersistent && !expiresUtc.HasValue)
options.SetSlidingExpiration(_rememberMeTimeoutInDays);
else if (ticket.Properties.IsPersistent && expiresUtc.HasValue)
options.SetSlidingExpiration(TimeSpan.FromTicks(expiresUtc.Value.Ticks));
else
options.SetSlidingExpiration(_defaultTimeoutInHours);
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
return Task.FromResult(0);
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413862%2fhow-to-create-a-persistent-ticket-in-redis%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
After tip from Kirk Larkin in a comment. It occurred to me that all i really needed to do was set the timeout longer then it would continue to slide it as long as the user was active. If i had set it to Persist then it would have been in redis forever and thats really not what we want. We want it in there for a given period of time as long as the user comes back from time to time they will continue to appear to be logged in.
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
options.SetAbsoluteExpiration(expiresUtc.Value);
if (ticket.Properties.IsPersistent && !expiresUtc.HasValue)
options.SetSlidingExpiration(_rememberMeTimeoutInDays);
else if (ticket.Properties.IsPersistent && expiresUtc.HasValue)
options.SetSlidingExpiration(TimeSpan.FromTicks(expiresUtc.Value.Ticks));
else
options.SetSlidingExpiration(_defaultTimeoutInHours);
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
return Task.FromResult(0);
}
add a comment |
After tip from Kirk Larkin in a comment. It occurred to me that all i really needed to do was set the timeout longer then it would continue to slide it as long as the user was active. If i had set it to Persist then it would have been in redis forever and thats really not what we want. We want it in there for a given period of time as long as the user comes back from time to time they will continue to appear to be logged in.
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
options.SetAbsoluteExpiration(expiresUtc.Value);
if (ticket.Properties.IsPersistent && !expiresUtc.HasValue)
options.SetSlidingExpiration(_rememberMeTimeoutInDays);
else if (ticket.Properties.IsPersistent && expiresUtc.HasValue)
options.SetSlidingExpiration(TimeSpan.FromTicks(expiresUtc.Value.Ticks));
else
options.SetSlidingExpiration(_defaultTimeoutInHours);
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
return Task.FromResult(0);
}
add a comment |
After tip from Kirk Larkin in a comment. It occurred to me that all i really needed to do was set the timeout longer then it would continue to slide it as long as the user was active. If i had set it to Persist then it would have been in redis forever and thats really not what we want. We want it in there for a given period of time as long as the user comes back from time to time they will continue to appear to be logged in.
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
options.SetAbsoluteExpiration(expiresUtc.Value);
if (ticket.Properties.IsPersistent && !expiresUtc.HasValue)
options.SetSlidingExpiration(_rememberMeTimeoutInDays);
else if (ticket.Properties.IsPersistent && expiresUtc.HasValue)
options.SetSlidingExpiration(TimeSpan.FromTicks(expiresUtc.Value.Ticks));
else
options.SetSlidingExpiration(_defaultTimeoutInHours);
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
return Task.FromResult(0);
}
After tip from Kirk Larkin in a comment. It occurred to me that all i really needed to do was set the timeout longer then it would continue to slide it as long as the user was active. If i had set it to Persist then it would have been in redis forever and thats really not what we want. We want it in there for a given period of time as long as the user comes back from time to time they will continue to appear to be logged in.
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
var options = new DistributedCacheEntryOptions();
var expiresUtc = ticket.Properties.ExpiresUtc;
if (expiresUtc.HasValue)
options.SetAbsoluteExpiration(expiresUtc.Value);
if (ticket.Properties.IsPersistent && !expiresUtc.HasValue)
options.SetSlidingExpiration(_rememberMeTimeoutInDays);
else if (ticket.Properties.IsPersistent && expiresUtc.HasValue)
options.SetSlidingExpiration(TimeSpan.FromTicks(expiresUtc.Value.Ticks));
else
options.SetSlidingExpiration(_defaultTimeoutInHours);
byte val = SerializeToBytes(ticket, _logger);
_cache.Set(key, val, options);
return Task.FromResult(0);
}
answered Nov 22 '18 at 13:27
DaImToDaImTo
43.3k1058236
43.3k1058236
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413862%2fhow-to-create-a-persistent-ticket-in-redis%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Because your
ticket.ExpiresUtc
has a value, you're callingoptions.SetAbsoluteExpiration(...)
- you're not checking whetherticket.IsPersistent
istrue
before doing this. Can't you just skip the calls tooptions.SetAbsoluteExpiration(...)
andoptions.SetSlidingExpiration(...)
whenticket.IsPersistent
istrue
?– Kirk Larkin
Nov 21 '18 at 14:23
If I dont set a sliding it grabs a number from the ExpiresUtc so i end up with a time out of 1209548 which is good. However will it continue to slide if the user logs in? I am still testing this.
– DaImTo
Nov 21 '18 at 14:34