ASP.NET 自定义声明的身份和验证
ASP.NET Identity and validation of a custom claim
我正在使用 ASP.NET Identity with MVC,我在每个登录用户的每个设备上设置了一个 sessionId(GuId 字符串)。这个想法是用户可以删除设备会话,然后该设备将不再登录(就像在保管箱中所做的那样,google)。
目前,我将此 sessionId 设置为 ASP.NET Identity 中的声明,因此它在身份验证 cookie 中传递。
对于身份验证,我使用 ASP.NET 身份作为样本:app.UseCookieAuthentication(new CookieAuthenticationOptions{....
我的问题:
将我的 sessionId 设置为声明的正确方法吗?
此外,在整个身份验证过程中,我可以在哪里验证该 sessionId 的声明?
我目前的想法是针对每个请求根据数据库 table 验证此 sessionId。我应该使用 Request.Sessions 来存储 sessionId 还是其他想法?
谢谢,
由于一个用户可以有多个有效会话,您需要将它们存储为声明或创建您自己的 table 来存储它们。由于声明已经由 Identity 创建,这将是最简单的。
您将在 Startup.Auth.cs
中 CookieAuthenticationProvider
的 OnValidateIdentity
方法中验证这一点。目前这会调用 SecurityStampValidator
的 OnValidateIdentity
方法,因此您需要编写一个包装方法,首先检查您的会话 ID,然后调用原始安全戳验证器。例如,您可以将这些方法添加到 Startup
class:
private Func<CookieValidateIdentityContext, System.Threading.Tasks.Task> _validate=SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager));
private async Task validate(CookieValidateIdentityContext context)
{
var usermanager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var claims = await usermanager.GetClaimsAsync(context.Identity.GetUserId());
//instead of setting to true, add your session validation logic here
bool sessionIsValid=true;
if (!sessionIsValid) {
context.RejectIdentity();
context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
}
await _validate(context);
}
其中 _validate
只是原始方法,validate
是您的新方法,它也检查会话 ID。然后您的 app.UseCookieAuthentication
代码将引用新的 validate
方法,如下所示:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = validate
}
});
为了完成这项工作,我认为您每次都需要从数据库中检查声明,但我相信 usermanager.GetClaimsAsync
最终会做到这一点。
我正在使用 ASP.NET Identity with MVC,我在每个登录用户的每个设备上设置了一个 sessionId(GuId 字符串)。这个想法是用户可以删除设备会话,然后该设备将不再登录(就像在保管箱中所做的那样,google)。
目前,我将此 sessionId 设置为 ASP.NET Identity 中的声明,因此它在身份验证 cookie 中传递。
对于身份验证,我使用 ASP.NET 身份作为样本:app.UseCookieAuthentication(new CookieAuthenticationOptions{....
我的问题:
将我的 sessionId 设置为声明的正确方法吗?
此外,在整个身份验证过程中,我可以在哪里验证该 sessionId 的声明?
我目前的想法是针对每个请求根据数据库 table 验证此 sessionId。我应该使用 Request.Sessions 来存储 sessionId 还是其他想法?
谢谢,
由于一个用户可以有多个有效会话,您需要将它们存储为声明或创建您自己的 table 来存储它们。由于声明已经由 Identity 创建,这将是最简单的。
您将在 Startup.Auth.cs
中 CookieAuthenticationProvider
的 OnValidateIdentity
方法中验证这一点。目前这会调用 SecurityStampValidator
的 OnValidateIdentity
方法,因此您需要编写一个包装方法,首先检查您的会话 ID,然后调用原始安全戳验证器。例如,您可以将这些方法添加到 Startup
class:
private Func<CookieValidateIdentityContext, System.Threading.Tasks.Task> _validate=SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager));
private async Task validate(CookieValidateIdentityContext context)
{
var usermanager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var claims = await usermanager.GetClaimsAsync(context.Identity.GetUserId());
//instead of setting to true, add your session validation logic here
bool sessionIsValid=true;
if (!sessionIsValid) {
context.RejectIdentity();
context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
}
await _validate(context);
}
其中 _validate
只是原始方法,validate
是您的新方法,它也检查会话 ID。然后您的 app.UseCookieAuthentication
代码将引用新的 validate
方法,如下所示:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = validate
}
});
为了完成这项工作,我认为您每次都需要从数据库中检查声明,但我相信 usermanager.GetClaimsAsync
最终会做到这一点。