Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug of Users Authentication Ticket Store Feature #13726

Closed
hyzx86 opened this issue May 21, 2023 · 12 comments
Closed

Bug of Users Authentication Ticket Store Feature #13726

hyzx86 opened this issue May 21, 2023 · 12 comments
Labels
Milestone

Comments

@hyzx86
Copy link
Contributor

hyzx86 commented May 21, 2023

oc version :preview-latest

Describe the bug

After enabling the Users Authentication Ticket Store feature,
whenever any other feature is enabled. The user is always redirected to the login page.

@hyzx86
Copy link
Contributor Author

hyzx86 commented May 21, 2023

It looks like here is always null

image

@hyzx86
Copy link
Contributor Author

hyzx86 commented May 21, 2023

I Debug the code and see that the following method is called after ShellScope.UsingAsync

OrchardCore.Users.Authentication.CacheTicketStore.RetrieveAsync

public async Task UsingAsync(Func<ShellScope, Task> execute, bool activateShell = true)
{
if (Current == this)
{
await execute(Current);
return;
}
using (this)
{
StartAsyncFlow();
try
{
try
{
if (activateShell)
{
await ActivateShellInternalAsync();
}
await execute(this);
}
finally
{
await TerminateShellInternalAsync();
}
}
catch (Exception e)
{
await HandleExceptionAsync(e);
throw;
}
finally
{
await BeforeDisposeAsync();
}
}
}

{
var cacheKey = $"{_keyPrefix}-{key}";
var cache = _httpContextAccessor.HttpContext.RequestServices.GetService<IDistributedCache>();
var bytes = await cache.GetAsync(cacheKey);
if (bytes == null || bytes.Length == 0)
{
return null;
}
try
{
var ticket = DeserializeTicket(DataProtector.Unprotect(bytes));
return ticket;
}
catch (Exception e)
{
// Data Protection Error
Logger.LogError(e, "{methodName} failed for '{key}'.", nameof(RetrieveAsync), cacheKey);
return null;
}
}

@hishamco
Copy link
Member

Into your plate @ns8482e :)

@ns8482e
Copy link
Contributor

ns8482e commented May 23, 2023

Correct it's expected behavior.
Bydefault the authentication ticket is stored in cookies. After enabling the Users Authentication Ticket Store feature, the authentication ticket is stored on server in IMemoryCache.

IMemoryCache is destroyed and recreated when tenant is reloaded.

To keep authentication ticket between tenant reload you should also enable and configure redis cache feature.

@hyzx86
Copy link
Contributor Author

hyzx86 commented May 23, 2023

So, should we save the Token to the database without Redis enabled?

At the moment, it seems that this problem will only arise on the site Settings changed

@ns8482e
Copy link
Contributor

ns8482e commented May 23, 2023

Yes you should not rely on IMemoryCache in production if your frequently update the features. In production You should use redid cache

@sebastienros
Copy link
Member

We could also have an implementation that is based on SQL. @hyzx86 you can file an issue, and maybe provide a PR for this?

For this current issue maybe we should display a notification/warning when no other specific ticket store is enabled.

@sebastienros sebastienros added this to the 1.x milestone May 25, 2023
@hyzx86
Copy link
Contributor Author

hyzx86 commented May 28, 2023

@sebastienros This is not a very urgent issue in my scenario right now; After all, it's reasonable to tell users that a configuration change caused them to log back in 😁

I actually feel like this part of the code is a little hard for me to change
Maybe we can add some documentation and close it, or someone else can fix the problem

@hyzx86
Copy link
Contributor Author

hyzx86 commented May 28, 2023

We could also have an implementation that is based on SQL

Well, if we start with that, it's really not difficult. I can try it

@hyzx86
Copy link
Contributor Author

hyzx86 commented May 28, 2023

To achieve this, should I re-implement a SqlDistributedCache? It's like

https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-6.0

This seems a bit complicated, but for distributed caching, shouldn't we make it a higher priority, such as enabling it only from the default site, and then separate the distributed caching object from the specific tenant?

Just like DatabaseShellsConfiguration

@sebastienros
Copy link
Member

Correct, you could create a feature that would register SqlDistributedCache as the IDistributedCache implementation. That would be easier than setting up a Redis instance for lots of deployments since SQL is already available for OC. And a migration would create the required tables.

@Piedone
Copy link
Member

Piedone commented Jul 16, 2024

#16149 covers SQL Distributed Cache, so we don't need to do anything specific for this module, and rather work on that.

@Piedone Piedone closed this as not planned Won't fix, can't repro, duplicate, stale Jul 16, 2024
@MikeAlhayek MikeAlhayek modified the milestones: 2.x, 2.0 Sep 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants