ASP.NET MVC 6自定义用户身份,长时间保持登录用户?
ASP.NET MVC 6 custom user identity, persisting the logged-in user for a long time?
所以我有 ASP.NET MVC 6 + AngularJS 具有自定义用户身份(不使用 EF)的应用程序,它可以在没有 EF 的情况下针对不同的数据库对用户进行身份验证,等等。
我有一些用户身份工作所需的一些接口的自定义实现。
IUserStore<MyUser>
、IUserPasswordStore<MyUser>
- 只实现了几个方法来让用户使用我的自定义代码。那里没什么有趣的。
IPasswordHasher<MyUser>
使用我自己的密码解密密码等验证散列密码的实现
IUserClaimsPrincipalFactory<MyUser>
创建 ClaimsPrincipal
对象的实现,其中包含我自己的一些自定义声明。
在用于登录和注销的 AccountControler
中,我使用的是:
SignInManager.PasswordSignInAsync(username, password, true, shouldLockout: false)
SignInManager.SignOut();
其中 SignInManager 是我自定义的 - SignInManager<MyUser>
。
到目前为止一切都很顺利。
现在 Startup.cs
我有:
public void ConfigureServices(IServiceCollection services)
{
...
services.TryAdd(ServiceDescriptor.Scoped<IUserStore<MyUser>, ApplicationUserStore>());
services.TryAdd(ServiceDescriptor.Scoped<IUserPasswordStore<MyUser>, ApplicationUserStore>());
services.TryAdd(ServiceDescriptor.Scoped<IPasswordHasher<MyUser>, ApplicationSitePasswordHasher>());
services.TryAdd(ServiceDescriptor.Scoped<IUserClaimsPrincipalFactory<MyUser>, MyUserClaimsPrincipalFactory>());
services.AddIdentity<MyUser, MyUserRole>();
services.ConfigureIdentity(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 1;
options.User.RequireUniqueEmail = false;
options.User.UserNameValidationRegex = string.Empty;
});
services.ConfigureIdentityApplicationCookie(options =>
{
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromDays(30);
options.AuthenticationScheme = IdentityOptions.ApplicationCookieAuthenticationScheme;
options.AutomaticAuthentication = true;
options.LoginPath = PathString.Empty;
});
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
...
app.UseIdentity();
...
app.UseMvc(routes => .... )
}
而且当用户在 angular http 异步调用中获得 401 时,我还有自定义授权属性处理。这个想法是这样的:
public class MyAuthorize : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
bool isAuth = bool isAuth = context.HttpContext.User.Identity.IsAuthenticated;
bool isFromClient = ...
string loginPath = ...
if (!isAuth && isFromClient)
{
...
}
else if (!isAuth && !isFromClient)
{
context.HttpContext.Response.Redirect(loginPath);
}
else
{
await next();
}
}
}
问题:即使我的 cookie 在 30 天后过期(在这种情况下),我仍然无法通过身份验证(context.HttpContext.User.Identity.IsAuthenticated
属性是 false
) 一段时间后,由于我在 MyAuthorize
属性中的逻辑而被重定向到登录页面。
IIS 池中的空闲超时也是 0。
如何让我的自定义用户身份在很长时间内保留经过身份验证的用户?
"some period of time" 是不是大约“登录后 30 分钟”? :)
实现IUserSecurityStampStore<User>
接口。
详细说明在
所以我有 ASP.NET MVC 6 + AngularJS 具有自定义用户身份(不使用 EF)的应用程序,它可以在没有 EF 的情况下针对不同的数据库对用户进行身份验证,等等。
我有一些用户身份工作所需的一些接口的自定义实现。
IUserStore<MyUser>
、IUserPasswordStore<MyUser>
- 只实现了几个方法来让用户使用我的自定义代码。那里没什么有趣的。IPasswordHasher<MyUser>
使用我自己的密码解密密码等验证散列密码的实现IUserClaimsPrincipalFactory<MyUser>
创建ClaimsPrincipal
对象的实现,其中包含我自己的一些自定义声明。
在用于登录和注销的 AccountControler
中,我使用的是:
SignInManager.PasswordSignInAsync(username, password, true, shouldLockout: false)
SignInManager.SignOut();
其中 SignInManager 是我自定义的 - SignInManager<MyUser>
。
到目前为止一切都很顺利。
现在 Startup.cs
我有:
public void ConfigureServices(IServiceCollection services)
{
...
services.TryAdd(ServiceDescriptor.Scoped<IUserStore<MyUser>, ApplicationUserStore>());
services.TryAdd(ServiceDescriptor.Scoped<IUserPasswordStore<MyUser>, ApplicationUserStore>());
services.TryAdd(ServiceDescriptor.Scoped<IPasswordHasher<MyUser>, ApplicationSitePasswordHasher>());
services.TryAdd(ServiceDescriptor.Scoped<IUserClaimsPrincipalFactory<MyUser>, MyUserClaimsPrincipalFactory>());
services.AddIdentity<MyUser, MyUserRole>();
services.ConfigureIdentity(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 1;
options.User.RequireUniqueEmail = false;
options.User.UserNameValidationRegex = string.Empty;
});
services.ConfigureIdentityApplicationCookie(options =>
{
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromDays(30);
options.AuthenticationScheme = IdentityOptions.ApplicationCookieAuthenticationScheme;
options.AutomaticAuthentication = true;
options.LoginPath = PathString.Empty;
});
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
...
app.UseIdentity();
...
app.UseMvc(routes => .... )
}
而且当用户在 angular http 异步调用中获得 401 时,我还有自定义授权属性处理。这个想法是这样的:
public class MyAuthorize : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
bool isAuth = bool isAuth = context.HttpContext.User.Identity.IsAuthenticated;
bool isFromClient = ...
string loginPath = ...
if (!isAuth && isFromClient)
{
...
}
else if (!isAuth && !isFromClient)
{
context.HttpContext.Response.Redirect(loginPath);
}
else
{
await next();
}
}
}
问题:即使我的 cookie 在 30 天后过期(在这种情况下),我仍然无法通过身份验证(context.HttpContext.User.Identity.IsAuthenticated
属性是 false
) 一段时间后,由于我在 MyAuthorize
属性中的逻辑而被重定向到登录页面。
IIS 池中的空闲超时也是 0。
如何让我的自定义用户身份在很长时间内保留经过身份验证的用户?
"some period of time" 是不是大约“登录后 30 分钟”? :)
实现IUserSecurityStampStore<User>
接口。
详细说明在