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

时间:2019-02-20 13:17:25

标签: c# session asp.net-core asp.net-core-identity

我是一般编码的新手,尤其是Asp.Net核心的编码,所以请原谅我。我真的很希望我的项目有所帮助。目前,我正在通过在登录时向不同的用户添加不同的TimeSpan来扯头发。假设来自 company 1 登录的示例用户,希望可以得到一个会话时间60分钟(即空闲时间),但是当公司2 的用户登录时,会话时间可能是默认的20分钟。

更新: 我的 Target框架 .Net Framework 4.6.1 ,但是代码是为 .Net Core 2.1 准备的,我正在运行身份软件包v2.1.2

我的startup类看起来像这样:

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("...");
            ...

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

        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,但未能成功解决。我想我首先需要能够检查用户的索偿要求(以查看用户所属的公司),并可能为特定公司设置值,例如 DB表中的 company 1 值60 ,然后读取该值并使用Db中的该值更新Timespan或以更“丑陋”的方式进行硬编码Startup中的值。假设该用户属于某个公司,那么该公司应具有特定的会话值,或者如果未设置默认值20分钟。例如,在伪指令中:(如果user.companyID等于1,则设置options.ExpireTimeSpan = TimeSpan.FromMinutes(60)),依此类推。我的问题是,我当然不能在启动时访问此值,也许不应该吗?

我也尝试过this,但是如果我没弄错我的话会扩展cookie到客户端,并且不会影响空闲的用户时间吗?而且它还使用了Session,我想我可以添加它,但我不确定无论如何对我来说都没有好处。

我也尝试尽可能多地遵循this文档。但是该框架似乎不支持多个/不同的ExpireTimeSpan设置。

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

1 个答案:

答案 0 :(得分:0)

我改为这样解决它:

    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选项,并且能够通过设置(appsettings.json,ENV等)覆盖SecurityStampValidatorOptionsCookieAuthenticationOptions的一部分我可以使用不同的设置来部署应用程序。

我找不到如何直接配置应用程序Cookie的方法 从“配置”部分中进行设置,以便设置所选的几个属性 如果设置可用。

因此它并不能解决我的真正问题,但这已经足够好了,因为我的部署选项和位置不同,因此可以解决此问题。

然后我可以在appsettings.json中这样做:

"SecurityStampValidatorOptions": {
  "ValidationInterval": "0.00:00:20"
    },
"CookieAuthenticationOptions": {
   "SlidingExpiration": true,
   "ExpireTimeSpan": "0.02:00:00"
  }

并覆盖默认值,并且首先要注意的是,Startup中没有硬编码的值。