简体   繁体   English

基于 IPAddress 和客户端设备在 asp.net 核心 3.1 身份中设置 Cookie Expiration 时间跨度

[英]Set Cookie Expiration time span based on IPAddress and client device in asp.net core 3.1 identity

I am upgrading to asp.net core 3.1 with identity.我正在升级到具有身份的 asp.net 核心 3.1。 Before I was setting cookies manually at login and updating each time the client made a request.在我在登录时手动设置 cookies 之前,每次客户端发出请求时都进行更新。

I would like to update the cookie expiration based on the clients IPAddress and device each time a request is made.我想在每次发出请求时根据客户端 IPAddress 和设备更新 cookie 过期时间。 Those who login from home would only get 4 hours, those who login from the office would get days, those who login from their iPhone would get a different amount of time.从家里登录的人只有 4 小时,从办公室登录的人会得到几天,从 iPhone 登录的人会得到不同的时间。

Is it possible to override asp.net core identities existing middleware that updates the cookie expiration datetime?是否可以覆盖更新 cookie 到期日期时间的现有中间件 asp.net 核心身份? I know you can set the cookie expiration in startup using:我知道您可以使用以下方法在启动时设置 cookie 过期时间:

        services.AddAuthentication()
                .AddCookie(cfg =>
                {
                    cfg.ExpireTimeSpan = TimeSpan.FromMinutes(20);
                    cfg.LoginPath = @"/Account/Login";
                    cfg.LogoutPath = @"/Account/Logout";
                    cfg.Cookie.Domain = ".MyDomain.com";
                    cfg.SlidingExpiration = true;
                });

But I do not want to set the expire time statically.但我不想静态设置过期时间。 Any help would be appreciated.任何帮助,将不胜感激。

I did a lot of research and found very little to make this possible.我做了很多研究,却发现很少能做到这一点。 I ended up creating my own middleware that updated the cookie on each request.我最终创建了自己的中间件,在每个请求上更新 cookie。 I am not sure the impact this has on load times but so far is hasn't effect load time much.我不确定这对加载时间有什么影响,但到目前为止对加载时间影响不大。

I set up identity and used the signin manager API as normal我设置了身份并正常使用了登录管理器 API

I set up Configure Services in my start up class like this:我在启动 class 中设置了配置服务,如下所示:

 public void ConfigureServices(IServiceCollection services)
 {
            //Other Services Here...    

            services.AddIdentity<User, IdentityRole>(cfg =>
            {
                cfg.User.RequireUniqueEmail = true;
            })
               .AddEntityFrameworkStores<SJRContext>()
               .AddSignInManager<SJRSignInManager<User>>()
               .AddDefaultTokenProviders()
               .AddTokenProvider<CustomTwoFactorTokenProvider<User>>("TwoFactorAuthToken");

            services.AddAuthentication()
                .AddCookie(cfg =>
                {
                    cfg.ExpireTimeSpan = TimeSpan.FromMinutes(20);
                    cfg.LoginPath = @"/Account/Login";
                    cfg.LogoutPath = @"/Account/Logout";
                    cfg.SlidingExpiration = true;
                    cfg.Cookie.Expiration = TimeSpan.FromMinutes(30);
                    cfg.Cookie.Domain = Configuration.GetSection("AppDomain").Value;
                });
}

I then signed the users in on my account controller like this:然后我在我的帐户 controller 上登录用户,如下所示:

var result = await _signInManager.PasswordSignInAsync(user, model.Password, true, false);
if (result.Succeeded)
{
   //Redirect
}
else
{ 
   //Return model error
}

And then I added my own custom middleware to my pipeline on Configure method of my start up class like this:然后我在我的启动 class 的配置方法上将我自己的自定义中间件添加到我的管道中,如下所示:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {

            //Other Middleware here...

            app.Use(async (ctx, next) =>
            {
                const string cookieName = ".AspNetCore.Identity.Application";
                //Get cookie
                var val = ctx.Request.Cookies[cookieName];

                if (string.IsNullOrEmpty(val) == false)
                {
                    //Init Constants
                    const int externalMaxHourLimit = 8;
                    const string sessionStartTime = "sessionStartTime";

                    //Get ip
                    var ip = ctx.Request.HttpContext.Connection.RemoteIpAddress.ToString();

                    //Get device type
                    var deviceType = ctx.Request.Headers["User-Agent"].ToString();

                    //Check ip
                    var isInHouse = WorkordersDomain.Security.Security.isIPAddressInSJRollins(ip);

                    //init cookie options
                    var cookieOptions = new CookieOptions()
                    {
                        SameSite = SameSiteMode.Strict,
                        Secure = true,
                        Domain = Configuration.GetSection("AppDomain").Value,
                        Expires = DateTime.Now.AddHours(Convert.ToInt32(Configuration.GetSection("CookieExpiration:Default").Value))
                    };

                    //Set cookie expiration
                    if (isInHouse)
                    {
                        cookieOptions.Expires = DateTime.Now.AddHours(Convert.ToInt32(Configuration.GetSection("CookieExpiration:InHouse").Value));
                    }
                    else if (deviceType.Contains("iphone"))
                    {
                        cookieOptions.Expires = DateTime.Now.AddDays(Convert.ToInt32(Configuration.GetSection("CookieExpiration:iPhone").Value));
                    }
                    else
                    {
                        //Default
                        if (ctx.Session.IsAvailable)
                        {
                            if (ctx.Session.Get(sessionStartTime) == null)
                            {
                                ctx.Session.SetString(sessionStartTime, DateTime.Now.ToString());
                            }
                            else
                            {
                                var sessionStart = Convert.ToDateTime(ctx.Session.GetString(sessionStartTime));
                                if (DateTime.Now > sessionStart.AddHours(externalMaxHourLimit))
                                {
                                    cookieOptions.Expires = DateTime.Now.AddMinutes(-10);
                                    ctx.Session.Remove(sessionStartTime);
                                }
                            }
                        }
                    }

                    //update cookie
                    ctx.Response.Cookies.Append(cookieName, val, cookieOptions);
                }

                //Go to next middleware
                await next();

            });

            //Other Middleware here...
}

This middleware gets the identity cookie based on the key ".AspNetCore.Identity.Application" That will always be the same and I use the context parameter to find out the user agent and IP address of the client.该中间件根据密钥“.AspNetCore.Identity.Application”获取身份cookie,这将始终相同,我使用上下文参数找出客户端的用户代理和IP地址。 Then I just need to return the new cookie in the response with the same key and value pair and it replaces the old cookie with the new cookie and updated expiration time.然后我只需要在响应中返回具有相同键和值对的新 cookie,它会用新 cookie 和更新的过期时间替换旧 cookie。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 .Net Core 3.1 Identity Server 4 中更改持久性 Cookie 过期时间 - How to Change Persistent Cookie Expiration Time in .Net Core 3.1 Identity Server 4 ASP.NET Core 3.1 中基于角色的授权,带有身份和外部登录 - Role based authorization in ASP.NET Core 3.1 with Identity and ExternalLogin 基于角色的.NET Core动态身份验证Cookie - .NET Core Dynamic Expiration of Identity Cookie Based On Role ASP.NET核心身份3 Cookie超时 - ASP.NET Core Identity 3 Cookie timeout 没有身份验证Asp.net核心的Cookie - Cookie without Identity Asp.net core 带有 Identity Core 和 Asp.net Core 3.1 的多重登录页面 - Multiple Login Page with Identity Core and Asp.net Core 3.1 c#Asp.net获取javascript中设置的Cookie到期时间始终返回01.01.0001 - c# Asp.net getting Cookie expiration time set in javascript always returns 01.01.0001 种子 ASP.NET .NET Core 3.1 中的身份用户和角色 - Seed ASP.NET Identity user and roles in .NET Core 3.1 在 Web 部署发布到远程 IIS 后,ASP.NET Core 3.1 身份持久化 cookie 身份验证仍然失败 - ASP.NET Core 3.1 identity persist cookie authentication after web deploy publish to remote IIS still fails 如何使用 MongoDB 实现 ASP.NET Core 3.1 Identity? - How to implement ASP.NET Core 3.1 Identity with MongoDB?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM