- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们有一个使用 Asp.Net 标识的产品,我们希望 cookie 过期时间是可配置的。ExpireTimeSpan 当前设置在 Visual Studio 使用新项目为您创建的 Startup.ConfigureAuth 类中。这是在启动时从配置文件获取时间,但我们希望能够从 webAPI 更改此值。就目前而言,webAPI 请求可以修改配置文件,但我们需要回收应用程序池才能使其生效。
一旦服务器已经启动并运行,是否有任何方法可以更改此值?
关于这个主题,我只找到了这个问题 ASP.NET Identity Change ExpireTimeSpan after ConfigureAuth但它要求一种方法来为单个 session 更改它,而我想为整个服务器全局更改它。
更新:我通过查看 Katana 源代码发现这些选项似乎存储在 Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware
类的公共(public)属性中,但我不知道以任何方式从我的应用程序中获取对正在使用的对象的引用。
最佳答案
这花了一些时间才弄清楚,但我相信我已经找到了正确的解决方案。这很有趣,因为我已经有了解决方案,只是没有探索范围内可用的选项。
CookieAuthenticationOptions
只提供一个钩子(Hook),一个委托(delegate)属性 OnValidateIdentity
。
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;
}
关于c# - 如何在 ConfigureAuth 后更改 Asp.Net Identity 中的 cookie ExpireTimeSpan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30170102/
我是一名优秀的程序员,十分优秀!