Asp.Net Core 2 MVC 身份验证:添加不同的会话时间

Asp.Net Core 2 MVC Authentication: Add different session times

我是一般编码的新手,特别是 Asp.Net 核心,所以请原谅我的笨拙。我真的希望对我的项目有所帮助。我现在在登录时向不同的用户添加不同的 TimeSpan 来撕裂我的头发。例如,来自 company 1 的用户登录并希望获得会话说 60 分钟的时间(即空闲时间)但是当来自 company 2 的用户登录时,会话时间可能是默认的 20 分钟。

更新: 我的目标框架.Net Framework 4.6.1,但代码是为.Net Core 2.1准备的我是 运行 Identity package v2.1.2

我的 startup class 看起来像这样:

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        CultureInfo.CurrentCulture = new CultureInfo("sv-SE");
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsDevelopment())
        {
            builder.AddUserSecrets<Startup>();
        }

        builder.AddInMemoryCollection(GetBeanstalkEnvironmentProperties());
        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IConfiguration>(Configuration);

        // Add framework services.
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("ExternalServerConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.Configure<EmailConfiguration>(Configuration.GetSection("EmailConfiguration"));
        services.AddMvc();

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();
    }

登录控制器就这么简单:

  public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                _logger.LogInformation(1, "User logged in.");
                
                return RedirectToAction("...");
            ...

并且在检查了不同的解决方案和论坛后,找到了 thisStartup 中添加 Timespan 的选项:

        services.Configure<SecurityStampValidatorOptions>(options =>
        {
            // Add validationinterval E.g how often the stamp is checked.
            options.ValidationInterval = TimeSpan.FromSeconds(10);
        });
        services.AddAuthentication().Services.ConfigureApplicationCookie(options =>
        {
            // Timespan extension if page is refreshed or navigated. Default is true.
            options.SlidingExpiration = true;
            // Cookie is valid at minimum 20 min.
            options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
        });

这工作正常,但这是为用户设置会话时间的全局方式,然后将应用于所有用户。所以我希望有人有一个很好的解决方案,我可以在其中使用上面的内容,并且仍然能够根据用户的偏好在此处添加不同的值 options.ExpireTimeSpan = TimeSpan.FromMinutes(20);,例如用户是哪个公司的会员。

其他参考资料和我到目前为止尝试过的内容。

我试图找出 this 一个结果,但在我的案例中没有成功。我想我首先需要能够检查用户的声明(以查看用户属于哪个公司)并且可能为特定公司设置一个值,例如company 1 DB 中的值 60 table 然后读取该值并使用 Db 中的该值更新 Timespan或者以更“丑陋”的方式只是硬编码 Startup 中的值。假设用户属于某个公司,那么它应该有一个特定的会话值,或者如果没有设置默认值 20 分钟。例如在伪中:(如果 user.companyID 等于 1,则设置 options.ExpireTimeSpan = TimeSpan.FromMinutes(60))等等。我的问题是,我当然不能在启动时访问这些值,也许不应该?

我也试过 this 但如果我没有弄错并且不会影响空闲用户时间,那会为客户端扩展 cookie?!它也使用 Session,我想我可以添加它,但我不确定这对我的情况有什么好处。

我也尽量遵循 this 文档。但是框架好像不支持multiple/differentExpireTimeSpan设置

Here 是另一个问题,目前还没有答案,我可以说出与我遇到的问题相同的问题。

我是这样解决的:

    services.Configure<SecurityStampValidatorOptions>(Configuration.GetSection("SecurityStampValidatorOptions"));

    services.AddAuthentication().Services.ConfigureApplicationCookie(options =>
            {
                var cookieAuthenticationOptions = Configuration
                   .GetSection(nameof(CookieAuthenticationOptions))
                   .Get<CookieAuthenticationOptions>();
                if (cookieAuthenticationOptions == null)
                    return;

                options.ExpireTimeSpan = cookieAuthenticationOptions.ExpireTimeSpan;
                options.SlidingExpiration = cookieAuthenticationOptions.SlidingExpiration;
            });

也许不是最好的方法,但我仍然可以使用 Services.ConfigureApplicationCookie 选项,并且能够从设置中覆盖 SecurityStampValidatorOptionsCookieAuthenticationOptions 的一部分(appsettings.json,ENV等),这样我就可以使用不同的设置部署应用程序。

我找不到如何直接配置应用程序 cookie 来自配置部分,因此设置了选定的几个属性 如果设置可用。

所以它没有解决我的真正问题,但这已经足够了,因为我有不同的部署选项和位置,所以它是一个可行的解决方案。

然后我可以在 appsettings.json:

中这样做
"SecurityStampValidatorOptions": {
  "ValidationInterval": "0.00:00:20"
    },
"CookieAuthenticationOptions": {
   "SlidingExpiration": true,
   "ExpireTimeSpan": "0.02:00:00"
  }

并覆盖默认值,而且在前期是 Startup.

中没有硬编码值