【问题标题】:Storing hash of username using ASP.NET identity使用 ASP.NET 标识存储用户名的哈希
【发布时间】:2015-05-04 18:17:21
【问题描述】:

我正在编写一个应用程序,该应用程序需要始终从数据库中删除/不存在个人身份信息。鉴于有人可能在他们的用户名中使用他们的真实姓名,并且他们的 AspUserIdentity 记录中可能存在一个电子邮件地址,我决定一种解决方案可能是散列这些值。简单来说:当有人使用用户名登录时,我对他们输入的用户名进行哈希处理,然后查看该哈希是否存在于数据库中;如果是这样,那么我将它们登录。这很容易做到,并且可以通过修改 AccountController 中的 Login 和 Register 方法来正常工作。但是现在我对输入的用户名一无所知......

我可以将用户名存储在会话中,但这似乎很简单。我想做的是更新成功登录后发送的cookie,以使用他们输入的用户名(而不是存储在数据库中的散列值)。这样 User.Identity.GetUserName() 返回纯文本用户名(而不是散列用户名)。对客户来说,这个过程应该是透明的(对我来说也是程序员)。

问题是:怎么做?最好的地方是什么?当谈到最新的 ASP.NET 身份时,我仍然相对较新。我在 Startup.Auth 中看到有很多与 cookie 相关的有趣内容,但我没有看到任何可以在登录时和发送之前修改 cookie 本身的地方。

这一切都在 Owin 自身的深处吗?

提前致谢,

【问题讨论】:

    标签: owin asp.net-identity-2 asp.net-authorization


    【解决方案1】:

    当用户登录并比较用户名的哈希值时,您可以添加他们的真实用户名作为对身份的声明。这被序列化为 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() 如果您在其他地方需要它。

    【讨论】:

    • 太棒了。正是我想要的。干杯。
    猜你喜欢
    • 2013-03-25
    • 1970-01-01
    • 2016-02-22
    • 2015-09-26
    • 1970-01-01
    • 2015-08-14
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多