使用ASP.NET标识

时间:2015-05-04 18:17:22

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

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

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

问题是:怎么样?什么是最好的地方?在谈到最新的ASP.NET身份时,我还是比较绿色。我在Startup.Auth中看到有很多与cookies有关的多汁内容,但我没有看到任何地方我可以在登录时和发送之前修改cookie本身。

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

提前致谢,

1 个答案:

答案 0 :(得分:1)

当用户登录并比较用户名的哈希时,您可以将他们的真实用户名添加为身份的声明。这被序列化为cookie,并且每次请求都可以与用户一起使用,但不能保存在DB中:

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()