[英]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.