30 分钟后,asp.net core 身份中缺少其他声明

The*_*ion 7 claims asp.net-core asp.net-core-identity asp.net-core-2.2

我将声明添加到声明主体身份并让用户登录。在后续请求中,添加的声明可在应用程序中任何位置的声明主体中使用,但只能持续 25 分钟。我没有测试过25到30分钟。30 分钟后,声明主体身份仍经过身份验证,但仅包含来自身份数据库的声明。登录时添加的“CookieClaim”丢失。声明主体身份“IsAuthenticated”仍然是 true,并且导航菜单等中的问候语仍然是“Hi emailaddress”。如果我们在20分钟内提出请求也没关系。

我希望只要用户登录,这些声明就可用。

该应用程序使用 OAuth 从多个外部提供商获取用户的访问令牌和其他信息,该信息用于整个应用程序的授权。我选择将声明中的信息放入cookie中,因为它可能会定期更改,并且不适合存储在Identity数据库中。

以下代码来自我用来演示的 asp.net core 2.2 应用程序的支架 LoginModel。它与我的主应用程序不完全相同,但添加了声明,输入“CookieClaim”并使用相同的方法登录。从“IdentityUser user...”开始的四行实际上是我对模板 asp.net core Web 应用程序所做的唯一更改(使用本地用户帐户,在搭建“登录”页面之后)

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            IdentityUser user = await _signInManager.UserManager.FindByEmailAsync(Input.Email);
            ClaimsPrincipal currentUser = await _signInManager.CreateUserPrincipalAsync(user);
            currentUser.Identities.ElementAt(0).AddClaim(new Claim("CookieClaim", "I am in the Cookie"));
            await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, currentUser, new AuthenticationProperties());

            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
Run Code Online (Sandbox Code Playgroud)

在此应用程序的身份数据库中,我添加了用户的声明,输入“IdentityDatabaseClaim”。此图显示了登录后索赔主体的索赔。对于前 25 分钟内的任何请求,这都不会改变:

登录后索赔,全部正确

30 分钟后,来自数据库的声明仍然存在,但登录时在 cookie 中发送的声明类型“CookieClaim”已不存在,如以下屏幕截图所示:

在此输入图像描述

请注意,此时 IsAuthenticated 对于声明主体身份仍然为 true,来自身份数据库的所有声明都在那里。

我尝试在 Startup.cs 中的 cookie 上设置 ExpireTimeSpan 但这没有效果。我很确定这个问题不是 cookie 过期,否则用户仍然无法通过身份验证。我还尝试在身份验证属性上设置 IsPersistent、IssuedUtc 和 ExpiresUtc,主要是为了省去任何人提供这些作为此问题答案的麻烦。没有什么区别。

我需要知道什么方法或设置导致 HttpContext(看似)忽略请求 cookie 中的数据并从身份数据库创建一个新的声明主体,以及我是否可以 a)关闭它或 b)捕获它的工作,以便我可以在删除声明之前保存声明,并在尝试通过下一个授权过滤器之前再次附加它们。

The*_*ion 0

仅当我们使用 Application.Identity 方案 (IdentityConstants.ApplicationScheme) 登录时,才会发生此行为。使用不同的方案登录,并且您添加到该身份的任何声明将与 cookie 一样持续。所以在Startup.cs中的ConfigureServices中:

services.AddAuthentication()
    .AddCookie("CustomClaimsCookie")
Run Code Online (Sandbox Code Playgroud)

然后登录时,在 OnGetCallbackAsync() 方法中,

ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
AuthenticationProperties props = new AuthenticationProperties();
props.StoreTokens(info.AuthenticationTokens);
await HttpContext.SignInAsync("CustomClaimsCookie", info.Principal, props);
Run Code Online (Sandbox Code Playgroud)