使用ASP.NET Core Identity重置Cookie并强制重新登录

本文介绍了在ASP.NET Core应用中如何使用Duende Identity Server重置Cookie并强制用户重新登录的方法,包括处理远程认证错误和清理本地Cookie缓存的具体实现方案。

重置Cookie并使用ASP.NET Core Identity强制重新登录

本文探讨了在使用Duende Identity Server联合Entra ID的ASP.NET Core应用程序中实现Cookie重置的方法。有时由于Cookie大小问题或未知的远程认证服务器错误,需要为最终用户重置Cookie。可以清除Cookie并强制重新登录。

代码:https://github.com/damienbod/DuendeProfileServiceAspNetCoreIdentity

设置

ASP.NET Core Web应用程序设置为使用通过ASP.NET Core Identity和Duende IdentityServer实现的身份服务器进行身份验证。身份提供程序使用OpenID Connect联合到Entra ID。在我们的用例中,Microsoft帐户作为访客被邀请到Entra ID租户中,并使用login.live.com对Microsoft帐户用户进行身份验证。我们希望为两个ASP.NET Core应用程序提供Cookie重置功能,并强制重新登录流程。用户可能仍在Entra ID或Live中通过身份验证,系统将自动重新对用户进行身份验证。这只是清理应用程序中的Cookie。如果需要注销,可以使用带有正确所需方案的标准SignOut方法。

重置

使用ASP.NET Core Razor Page发送Cookie重置POST请求。

1
2
3
<form method="post">
    <input type="submit" class="btn btn-warning" name="Reset">
</form>

POST请求删除身份提供程序应用程序的所有Cookie,并使用HTTP重定向重定向到OpenID Connect客户端。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public IActionResult OnPost()
{
    // 如果需要,清除缓存
    foreach (var cookie in Request.Cookies.Keys)
    {
        Response.Cookies.Delete(cookie);
    }
    
    // 如果需要,冒泡到UI应用程序
    return Redirect("https://localhost:5015/resetcache");
}

HTTP GET重定向删除OpenID Connect客户端应用程序上的所有Cookie,并重定向到需要已认证用户的默认页面。默认的质询机制启动并开始身份验证流程。如果用户在Entra ID上已通过身份验证,系统将静默重新验证身份。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[AllowAnonymous]
public class Index : PageModel
{
    public IActionResult OnGet()
    {
        // 清除Cookie缓存
        foreach (var cookie in Request.Cookies.Keys)
        {
            Response.Cookies.Delete(cookie);
        }
        
        // 强制重新登录
        return Redirect("/");
    }
}

处理远程错误

Cookie重置可用于处理未知的OpenID Connect远程身份验证错误,这些错误有时会因未知原因失败,用户不重置本地Cookie无法恢复。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
OnRemoteFailure = async context =>
{
    var logger = context.HttpContext
        .RequestServices.GetRequiredService<ILogger<Program>>();
        
    logger.LogInformation(
        "身份提供程序的OnRemoteFailure。方案:{Scheme: }",
        context.Scheme.Name);
        
    if (context.Failure != null)
    {
        //server_error
        context.HandleResponse();
        context.Response.Redirect(
            $"/Home/Reset?remoteError={context.Failure.Message}");
    }
    
    await Task.CompletedTask;
}

注意事项

通常这不应该需要。如果需要注销,应使用默认的注销逻辑。此逻辑仅用于本地重置,不会注销用户。也不建议在HTTP GET上更改状态,但这是使其工作所必需的。

为什么不直接注销?

使用SignOut方法是注销ASP.NET Core应用程序的正确方式。使用不同的方案,可以注销每个方案。从浏览器中删除Cookie不会注销用户。这只是清理本地Cookie及其后面保存的内容。

关于缓存?

如果会话存储在服务器会话或服务器缓存中,那么您需要清理这些内容,而不仅仅是Cookie。

外部身份提供程序会发生什么?

我们无法直接控制这一点,也无法控制此处的会话。要删除会话,您需要向OpenID Connect服务器发送endsession请求。

链接

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计