如何在ConfigureAuth之后更改Asp.Net Identity中的cookie ExpireTimeSpan

2024-01-04

我们有一个使用 Asp.Net 身份的产品,我们希望 cookie 过期时间是可配置的。 ExpireTimeSpan 当前在 Visual Studio 通过新项目为您创建的 Startup.ConfigureAuth 类中设置。这是在启动时从配置文件获取时间,但我们希望能够从 webAPI 更改此值。 目前来看,webAPI 请求可以修改配置文件,但我们需要回收应用程序池才能使其生效。

一旦服务器已经启动并运行,有什么方法可以更改这个值吗?

我在这个主题上找到的只是这个问题配置验证后 ASP.NET 身份更改 ExpireTimeSpan https://stackoverflow.com/q/27281272/1093406但它要求一种方法来更改单个会话,而我想为整个服务器全局更改它。

更新:我通过查看 Katana 源代码发现这些选项似乎存储在该类的公共属性中Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware但我不知道有什么方法可以从我的应用程序中获取对正在使用的对象的引用。


这花了一些时间来弄清楚,但我相信我已经找到了正确的解决方案。这很有趣,因为我已经有了解决方案,只是没有探索范围内可用的选项。

CookieAuthenticationOptions只提供一个钩子,一个委托属性OnValidateIdentity.

The OnValidateIdentity每次有人登录(通过 cookie 身份验证提供程序)时都会发生,这恰好是运行一些自定义逻辑来确定新的到期时间的最佳时机。 它还允许您进行全局配置。

我已经调试过了并且可以确认配置选项的值sticks,并保留以供将来登录globally直到应用程序池回收。此外,过期值覆盖适用于登录回调后经过身份验证的用户。

因此,由您决定什么逻辑决定该值,以及您是否想要在个人级别或全局级别上设置它。

这是代码示例,可帮助更好地描述这一点。

public void ConfigureAuth(IAppBuilder app) {
    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
    app.CreatePerOwinContext<ApplicationGroupManager>(ApplicationGroupManager.Create);
    app.CreatePerOwinContext<ApplicationDepartmentManager>(ApplicationDepartmentManager.Create);

    app.UseCookieAuthentication(new CookieAuthenticationOptions {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Login"),
        Provider = new CookieAuthenticationProvider {

            OnValidateIdentity = delegate(CookieValidateIdentityContext context) {
                var stampValidator = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                    validateInterval: TimeSpan.FromMinutes(15),
                    regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                    getUserIdCallback: (id) => (id.GetUserId<int>())
                );
                Task result = stampValidator.Invoke(context);

                bool found_custom_expiration = false;
                int timeout = STATIC_CONFIG.DefaultSessionExpireMinutes;
                DBHelper.Query(delegate (SqlCommand cmd) {
                    cmd.CommandText = @"
                        SELECT [value] 
                        FROM [dbo].[Vars] 
                        WHERE [FK_Department] = (
                            SELECT [Id] FROM [dbo].[ApplicationDepartments] WHERE [title] = 'Default'
                        ) 
                        AND [name]='Session Timeout'
                    ";
                    return cmd;
                }, delegate (SqlDataReader reader) {
                    timeout = reader["value"].ToInt32();
                    found_custom_expiration = true;
                    return false;
                });
                if (found_custom_expiration) {
                    // set it at GLOBAL level for all users.
                    context.Options.ExpireTimeSpan = TimeSpan.FromMinutes(timeout);
                    // set it for the current user only.
                    context.Properties.ExpiresUtc = context.Properties.IssuedUtc.Value.AddMinutes(timeout);
                }
                // store it in a claim, so we can grab the remaining time later.
                // credit: https://stackoverflow.com/questions/23090706/how-to-know-when-owin-cookie-will-expire
                var expireUtc = context.Properties.ExpiresUtc;
                var claimType = "ExpireUtc";
                var identity = context.Identity;
                if (identity.HasClaim(c => c.Type == claimType)) {
                    var existingClaim = identity.FindFirst(claimType);
                    identity.RemoveClaim(existingClaim);
                }
                var newClaim = new System.Security.Claims.Claim(claimType, expireUtc.Value.UtcTicks.ToString());
                context.Identity.AddClaim(newClaim);
                return result;
            }
        },
        SlidingExpiration = true,
        // here's the default global config which was seemingly unchangeable.. 
        ExpireTimeSpan = TimeSpan.FromMinutes(STATIC_CONFIG.DefaultSessionExpireMinutes)
    });

    ApplicationHandler.OwinStartupCompleted();

}

这绝对可以改进,仅在尚未更改时才发布更改。而且您不必使用数据库查询,它可以是 XML 读取,或 web.config appsetting,或其他。 身份已就位...因此您甚至可以访问context.Identity并执行某种自定义检查ApplicationUser .

所以...相关的位...

OnValidateIdentity = delegate(CookieValidateIdentityContext context) {
            var stampValidator = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                getUserIdCallback: (id) => (id.GetUserId<int>())
            );
            Task result = stampValidator.Invoke(context);

            int my_custom_minutes = 60; // run your logic here.
                // set it at GLOBAL level for all (future) users.
                context.Options.ExpireTimeSpan = TimeSpan.FromMinutes( my_custom_minutes );
                // set it for the current user only.
                context.Properties.ExpiresUtc = context.Properties.IssuedUtc.Value.AddMinutes( my_custom_minutes );

            return result;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在ConfigureAuth之后更改Asp.Net Identity中的cookie ExpireTimeSpan 的相关文章

  • Web UI 中的 .Result 出现死锁

    我正在阅读以下主题http blog stephencleary com 2012 07 dont block on async code html http blog stephencleary com 2012 07 dont bloc
  • 如何向 UWP 项目添加 .NET dll 引用?

    我有几个适用于 NETv4 x 的 NET dll 项目 我将版本更改为 4 6 1 并重新构建 没有出现问题 当我尝试从 UWP 项目向它们添加引用时 出现错误 项目的目标是 NETCore 而文件引用的目标是 NET框架 这不是受支持的
  • 有没有比这更快的方法来查找目录和所有子目录中的所有文件?

    我正在编写一个程序 需要在目录及其所有子目录中搜索具有特定扩展名的文件 这将在本地驱动器和网络驱动器上使用 因此性能是一个问题 这是我现在使用的递归方法 private void GetFileList string fileSearchP
  • 我应该在单元测试中使用 AutoMapper 吗?

    我正在为 ASP NET MVC 控制器方法编写单元测试 这些控制器依赖于IMapper 我创建的用于抽象 AutoMapper 的接口 使用 Castle Windsor 通过构造函数注入传入 动作方法使用IMapper从领域对象映射到
  • 使用 C# 使用应用程序密码登录 Office 365 SMTP

    在我们的 Office 365 公司帐户中实施两步身份验证之前 我的 C WPF 程序已成功进行身份验证并发送邮件 我使用了 SmtpClient 库 但现在我必须找到另一个解决方案 因为它不再起作用 我找不到任何使用 O365 应用程序密
  • 浮点提升:stroustrup vs 编译器 - 谁是对的?

    在 Stroustrup 的新书 C 编程语言 第四版 第 10 5 1 节中 他说 在执行算术运算之前 整数提升用于从较短的整数类型创建整数 类似地 浮点提升是用于从浮点数创建双精度数 我用以下代码确认了第一个声明 include
  • __FUNCTION__ 宏的 C# 版本

    有人对 C FUNCTION 宏的 C 版本有好的解决方案吗 编译器似乎不喜欢它 尝试使用这个代替 System Reflection MethodBase GetCurrentMethod Name C 没有 LINE or FUNCTI
  • 控制台应用程序 .net Core 2.0 的配置

    在 net Core 1 中我们可以这样做 IConfiguration config new ConfigurationBuilder AddJsonFile appsettings json true true Build 这样就可以使
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • 如何检测斑点并将其裁剪成 png 文件?

    我一直在开发一个网络应用程序 我陷入了一个有问题的问题 我会尝试解释我想要做什么 在这里您看到第一个大图像 其中有绿色形状 我想要做的是将这些形状裁剪成不同的 png 文件 并使它们的背景透明 就像大图像下面的示例裁剪图像一样 第一张图像将
  • 当格式字符串包含“{”时,String.Format 异常

    我正在使用 VSTS 2008 C Net 2 0 执行以下语句时 String Format 语句抛出 FormatException 有什么想法是错误的吗 这是获取我正在使用的 template html 的位置 我想在 templat
  • 在生产者-消费者情况下使用条件变量

    我正在尝试了解条件变量以及如何在生产者 消费者情况下使用它 我有一个队列 其中一个线程将数字推入队列 而另一个线程从队列中弹出数字 当生产线程放置一些数据时 我想使用条件变量向消费线程发出信号 问题是有时 或大多数时候 它只将最多两个项目推
  • 为什么以下代码不允许我使用 fgets 获取用户输入但可以使用 scanf?

    这是一个更大程序的简短摘录 但该程序的其余部分无关紧要 因为我认为我能够隔离该问题 我怀疑这与我使用 fgets 的方式有关 我读过 最好使用 fgets 而不是 scanf 但我似乎无法让它在这里正常工作 当我使用以下代码时 程序不会给我
  • 抽象类和接口之间的区别[重复]

    这个问题在这里已经有答案了 可能的重复 接口与基类 https stackoverflow com questions 56867 interface vs base class 我不明白抽象类和接口之间的区别 我什么时候需要使用哪种字体
  • 用 C# 编写的带有点击移动的 WPF 游戏

    我试图将标签网格移动到鼠标的位置 就像冒险游戏中的移动一样 理想情况下 我会在途中删除并重新绘制它们 但是 现在我只想弄清楚如何将 int 转换为厚度或 pointtoscreen 到目前为止我有 player XMove int Mous
  • 多个同名内存数据库

    关系到这个答案 https stackoverflow com a 48446491 596758 我试图通过设置让多个上下文工作UseInMemoryDatabase以同名 下面的测试失败 第二个上下文为空 我还需要做什么才能在内存数据库
  • 如何使用 g++ 在 c++ 20 中使用模块?

    我读了这个链接https gcc gnu org wiki cxx modules https gcc gnu org wiki cxx modules并尝试从该网站复制以下示例 我已经知道这个编译器部分支持模块系统 注 我用的是windo
  • 从 C# 中的 .NET SecureString 读取单个字符?

    WPF 的PasswordBox 返回一个SecureString 它对窥探者隐藏密码 问题是你最终必须获得密码的值 而我在网上找到的建议都涉及将值复制到字符串中 这会让你回到窥探者的问题 IntPtr bstr Marshal Secur
  • 重叠的回收和Application_Start

    我有一个使用 AppFabric 进行分布式缓存的 asp net Web 应用程序 在 Application Start 上 我初始化与 AppFabric 的连接 这通常需要几毫秒 这是完全可以接受的 有时可能需要长达30秒连接 在回
  • C++0x 中的新 unicode 字符

    我正在构建一个 API 它允许我获取各种编码的字符串 包括 utf8 utf16 utf32 和 wchar t 根据操作系统 可能是 utf32 或 utf16 新的 C 标准引入了新类型char16 t and char32 t没有这么

随机推荐