【发布时间】:2021-06-14 23:02:53
【问题描述】:
我正在使用 .NET Core 2-3 和 EF Identity cookie 身份验证,并且我需要能够将任何给定用户从他们登录的所有浏览“会话”中注销。
为此,我使用以下授权过滤器“使 cookie 无效”:
public class CookieIsValidRequirementHandler : AuthorizationHandler<CookieIsValidRequirement>
{
private readonly ILogger _logger;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IHttpContextAccessor _httpContextAccessor;
public CookieIsValidRequirementHandler(
ILogger<CookieIsValidRequirementHandler> logger,
SignInManager<IdentityUser> signInManager,
IHttpContextAccessor httpContextAccessor
) {
_logger = logger;
_signInManager = signInManager;
_httpContextAccessor = httpContextAccessor;
}
protected override async Task HandleRequirementAsync(
AuthorizationHandlerContext context,
CookieIsValidRequirement requirement)
{
_logger.LogDebug("Checking if cookie is valid...");
Claim userIdClaim = context.User.FindFirst(ClaimTypes.NameIdentifier);
if (userIdClaim == null || string.IsNullOrWhiteSpace(userIdClaim.Value))
{
_logger.LogDebug($"NameIdentifier Claim not found");
context.Succeed(requirement); // This is needed to allow the home page to load
return;
}
else
{
if (requirement.userIdsToLogOut.Contains(userIdClaim.Value))
{
_logger.LogInformation("Cookie is invalid! Logging user out!");
await _signInManager.SignOutAsync();
requirement.userIdsToLogOut.Remove(userIdClaim.Value);
_logger.LogInformation($"CAN I USE THIS??? {_httpContextAccessor.HttpContext}");
}
else
{
_logger.LogDebug("Cookie is valid!");
context.Succeed(requirement);
}
}
}
这实际上工作得很好,除了它将用户重定向到:
https://localhost:5001/Identity/Account/Login?ReturnUrl=%2FIdentity%2FAccount%2FAccessDenied%3FReturnUrl%3D%252F
我喜欢它将他们重定向到登录页面,但请注意 ReturnUrl 是访问拒绝页面。我不想那样。
我试过在这里查看黑匣子:https://github.com/dotnet/aspnetcore
而且看起来身份验证模型与使用启动类中可用的少量选项“配置”的“方案”密切相关。
【问题讨论】:
-
如果您可以窥视黑匣子,它就不再是黑匣子了 :) 我认为您需要在特定环境中调试代码以找出问题所在。这是退出的源代码:github.com/dotnet/aspnetcore/blob/… - 您可以看到重定向 URL 是如何构建的。尝试在调试时检查可能的值。如果可能,您甚至可以启用 Source Link 调试以调试源代码以便更好地检查。
-
只是好奇,你怎么知道去哪里获取那个 blob 链接?我似乎无法有效地浏览 GitHub 上的源代码。
-
您可以从具有您使用的方法/属性的类中进行跟踪。这里是
SignInManager。有时你需要猜测默认实现(因为我们只知道接口),这里的重点是要知道默认逻辑。 github页面对帮助你快速找到你需要的东西不是很有帮助,例如:SignInManager搜索了6页结果,但是类在第6页(有时多达20多页) . -
框架团队采用了非常好的命名约定,因此很容易猜测默认实现(例如:几乎就像删除了
I的接口名称或 前缀为Default)。要找到确切的实现类型,有时您需要彻底阅读代码,这样会花费一些时间。 -
如果下载源代码并使用 Visual Studio 查找类,那么它会快得多(我还没有尝试过)。最后,要找到确切的实现类型(在运行时),而不是阅读代码,您可以在 Source Link 的支持下对其进行调试(google for more about it)。随着步骤的继续,它将引导您进入包含它运行的类的文件(将首先下载)。
标签: asp.net-core redirect authorization logout