使用 ASP.NET 身份存储用户名的哈希值
Storing hash of username using ASP.NET identity
我正在编写一个应用程序,它需要始终从 数据库 中获取个人身份信息 removed/absent。鉴于有人可能在用户名中使用他们的真实姓名,并且电子邮件地址可能存在于他们的 AspUserIdentity 记录中,我决定一种解决方案可能是散列这些值。简单来说:当有人使用用户名登录时,我对他们输入的用户名进行哈希运算,然后查看该哈希值是否存在于数据库中;如果是,那么我将它们登录。这很容易做到,并且通过修改 AccountController 中的登录和注册方法就可以很好地工作。但是现在我不知道输入的用户名...
我可以将用户名存储在会话中,但这看起来很简陋。我想做的是更新成功登录后发送的 cookie,以使用他们输入的用户名(而不是存储在数据库中的散列值)。这样 User.Identity.GetUserName() returns 纯文本用户名(而不是哈希用户名)。对于客户来说,这个过程应该是透明的(对于作为程序员的我来说也是如此)。
问题是:如何?最好的地方是什么?对于最新的 ASP.NET Identity 内容,我仍然比较陌生。我在 Startup.Auth 中看到有很多与 cookie 相关的有趣内容,但我看不到任何可以在登录时和发送之前修改 cookie 本身的地方。
这一切都深藏在欧文的内心深处吗?
提前致谢,
当用户登录并且您比较用户名的哈希值时,您可以添加他们的真实用户名作为对身份的声明。这被序列化到 cookie 中,并在每次请求时可供用户使用,但不会持久保存在数据库中:
public async Task SignIn(string userName, string password, bool rememberMe)
{
var hashedUsername = getMyHash(username)
var loggedInUser = await userManager.FindAsync(hashedUsername, password);
if (loggedInUser == null)
{
// failed to login
return FailedToLogin(); // whatever you do there
}
// Ok, from now on we have user who provided correct username and password.
// and because correct username/password was given, we reset count for incorrect logins. This is for user lockout
await userManager.ResetAccessFailedCountAsync(loggedInUser.Id);
if (!loggedInUser.EmailConfirmed)
{
return EmailIsNotConfirmed(); // email is not confirmed - display a message
}
if (await userManager.IsLockedOutAsync(loggedInUser.Id))
{
return UserLockedOut(); // user is locked out - display a message
}
var identity = await userManager.CreateIdentityAsync(loggedInUser);
identity.AddClaim(new Claim("OriginalUsername", originalUsername));
var authenticationManager = context.GetOwinContext().Authentication;
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = rememberMe }, identity);
//TODO redirect to a home page
}
然后当您需要显示实际用户名而不是哈希值时,请执行以下操作:
public static String GetOriginalUsername(this IPrincipal principal)
{
if (principal == null)
{
return String.Empty;
}
var claimsPrincipal = principal as ClaimsPrincipal;
if (claimsPrincipal == null)
{
return String.Empty;
}
var originalUsernameClaim = principal.Claims.SingleOrDefault(c => c.Type == "OriginalUsername");
if (originalUsernameClaim == null)
{
return String.Empty;
}
return originalUsernameClaim.Value;
}
并在 *.cshtml 文件或控制器中的 User.GetOriginalUsername()
上调用此方法。或者 HttpContext.Current.User.GetOriginalUsername()
如果您在其他地方需要它。
我正在编写一个应用程序,它需要始终从 数据库 中获取个人身份信息 removed/absent。鉴于有人可能在用户名中使用他们的真实姓名,并且电子邮件地址可能存在于他们的 AspUserIdentity 记录中,我决定一种解决方案可能是散列这些值。简单来说:当有人使用用户名登录时,我对他们输入的用户名进行哈希运算,然后查看该哈希值是否存在于数据库中;如果是,那么我将它们登录。这很容易做到,并且通过修改 AccountController 中的登录和注册方法就可以很好地工作。但是现在我不知道输入的用户名...
我可以将用户名存储在会话中,但这看起来很简陋。我想做的是更新成功登录后发送的 cookie,以使用他们输入的用户名(而不是存储在数据库中的散列值)。这样 User.Identity.GetUserName() returns 纯文本用户名(而不是哈希用户名)。对于客户来说,这个过程应该是透明的(对于作为程序员的我来说也是如此)。
问题是:如何?最好的地方是什么?对于最新的 ASP.NET Identity 内容,我仍然比较陌生。我在 Startup.Auth 中看到有很多与 cookie 相关的有趣内容,但我看不到任何可以在登录时和发送之前修改 cookie 本身的地方。
这一切都深藏在欧文的内心深处吗?
提前致谢,
当用户登录并且您比较用户名的哈希值时,您可以添加他们的真实用户名作为对身份的声明。这被序列化到 cookie 中,并在每次请求时可供用户使用,但不会持久保存在数据库中:
public async Task SignIn(string userName, string password, bool rememberMe)
{
var hashedUsername = getMyHash(username)
var loggedInUser = await userManager.FindAsync(hashedUsername, password);
if (loggedInUser == null)
{
// failed to login
return FailedToLogin(); // whatever you do there
}
// Ok, from now on we have user who provided correct username and password.
// and because correct username/password was given, we reset count for incorrect logins. This is for user lockout
await userManager.ResetAccessFailedCountAsync(loggedInUser.Id);
if (!loggedInUser.EmailConfirmed)
{
return EmailIsNotConfirmed(); // email is not confirmed - display a message
}
if (await userManager.IsLockedOutAsync(loggedInUser.Id))
{
return UserLockedOut(); // user is locked out - display a message
}
var identity = await userManager.CreateIdentityAsync(loggedInUser);
identity.AddClaim(new Claim("OriginalUsername", originalUsername));
var authenticationManager = context.GetOwinContext().Authentication;
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = rememberMe }, identity);
//TODO redirect to a home page
}
然后当您需要显示实际用户名而不是哈希值时,请执行以下操作:
public static String GetOriginalUsername(this IPrincipal principal)
{
if (principal == null)
{
return String.Empty;
}
var claimsPrincipal = principal as ClaimsPrincipal;
if (claimsPrincipal == null)
{
return String.Empty;
}
var originalUsernameClaim = principal.Claims.SingleOrDefault(c => c.Type == "OriginalUsername");
if (originalUsernameClaim == null)
{
return String.Empty;
}
return originalUsernameClaim.Value;
}
并在 *.cshtml 文件或控制器中的 User.GetOriginalUsername()
上调用此方法。或者 HttpContext.Current.User.GetOriginalUsername()
如果您在其他地方需要它。