【问题标题】:ASP.NET Identity 2.2.1 - send confirmation email with code, not with linkASP.NET Identity 2.2.1 - 发送带有代码的确认电子邮件,而不是带有链接
【发布时间】:2017-03-08 19:38:28
【问题描述】:

我已经使用 ASP.NET Identity 2.2.1 成功构建了简单的注册系统。
我只需要 API,所以我构建了简单的控制器,允许使用路由 account/create 创建帐户,当创建帐户时,用户会收到带有确认其手机所需令牌的 SMS 消息,同时我正在生成所需的链接验证电子邮件地址,我将其发送到用户电子邮件地址。 然后用户需要从 SMS 中输入令牌(向account/confirm_phone 请求)并单击他收到的电子邮件中的链接。
这两个操作是激活帐户所需要的,这部分工作正常。

我需要将电子邮件链接更改为电子邮件令牌,类似于用于确认电话号码的电子邮件,因此用户必须输入该令牌而不是单击链接(请求account/confirm_email

方法 GenerateEmailConfirmationTokenAsync 返回非常长的代码,该代码将成为电子邮件中链接的一部分,我希望它返回 6 位令牌。

我不能重复使用GeneratePhoneConfirmationTokenAsync,因为这将生成与通过 SMS 发送相同的令牌。

我在互联网上进行了搜索,但找不到任何有关如何自定义 GenerateEmailConfirmationTokenAsync 方法生成的令牌的信息。

是否可以配置该令牌生成器,使其返回 6 个(或任何可配置长度)数字代码,我可以使用它来确认用户电子邮件地址。

我知道将链接发送给用户是更好的选择,但正如我写的那样,这是我得到的要求,我无法更改。

【问题讨论】:

  • 所以您同时向电子邮件和手机发送确认信息?
  • @trailmax 是的,但这些应该是不同的代码。一个用于确认电话号码,第二个用于确认电子邮件地址。
  • 我明白了。在其中一个系统中,我做过类似的事情。但是我已经存储了一个带有到期时间的确认码。然后将用户提供的与存储的进行比较。您也可以这样做 - 使用到期时间戳存储两个代码并自己生成代码(而不是使用身份)。
  • @trailmax 感谢您的提示。我在考虑类似的事情,但我查看了 Identity 的源代码,发现代码负责生成电话号码令牌。我正在考虑使用类似的东西,但使用电子邮件作为修饰符而不是电话号码。我想避免数据库中的这两个字段并从盐和电子邮件地址生成该令牌,但我不知道如何设置该 nee 令牌的生命周期。
  • 那么你就走上了正轨。我记得我在令牌生成代码的某处看到了生命周期属性。继续挖掘。如果你还需要的话,我今晚可以看看它

标签: c# asp.net asp.net-web-api asp.net-identity-2


【解决方案1】:

这可能不是那么容易,但方法是编写自己的 IUserTokenProvider 实现。

public class CustomTokenProvider : IUserTokenProvider<ApplicationUser, string>
{
    public Task<string> GenerateAsync(string purpose, UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }

    public Task<bool> IsValidProviderForUserAsync(UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }

    public Task NotifyAsync(string token, UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }

    public Task<bool> ValidateAsync(string purpose, string token, UserManager<ApplicationUser, string> manager, ApplicationUser user)
    {
        ???
    }
}

然后在 ApplicationUserManager 的 Create 方法中:

manager.UserTokenProvider = new CustomTokenProvider<ApplicationUser, string>();

【讨论】:

  • 感谢您的回答,但我不想更改 UserTokenProvider,因为我想保留重置密码功能。我只需要其他方式的电子邮件确认 - 通过令牌。
【解决方案2】:

我对此进行了仔细查看,恐怕您不走运。

ASP.Net 身份框架 (v2.2.x) 有 2 个令牌提供者:DataProtectorTokenProviderEmailTokenProvider

DataProtectorTokenProvider 为您提供了一个非常长的令牌,不适合手动复制粘贴。但它允许设置时间跨度:DataProtectorTokenProvider.TokenLifespan。默认情况下,它设置为 1 天 - 请参阅该类的构造函数。此提供程序生成的令牌包含当前 UTC 时间、用户 ID、安全标记和附加字符串 purpose,可以是任何内容,但在验证时必须与生成时相同。这通常是“电子邮件”或“电话”。然后所有这些数据都由IDataProtector 加密。因此,您会得到非常长且看起来很讨厌的字符串。

您可以为不同的令牌设置可变的生命周期,但在验证每个特定令牌之前,您必须在 DataProtectorTokenProvider.TokenLifespan 中设置正确的值。

另一个选项EmailTokenProvider - 这个类继承自TotpSecurityStampBasedTokenProvider。此令牌提供程序基于 Rfc6238 生成一次性密码 (OTP)。这个令牌是时间敏感的,一旦超过时间窗口就会失效。有关详细信息,请参阅section 5.2。身份的默认时间窗口设置为 3 分钟。见行:

private static readonly TimeSpan _timestep = TimeSpan.FromMinutes(3);

Rfc6238AuthenticationService。但是 Rfc6238 说实现必须允许超过 1 个时间窗口。给定的实现允许总共 6 分钟的令牌寿命。如果不实现自己的 Rfc6238,就无法改变这一点。

因此,Identity 不会为您提供实现您的要求的方法 - 您必须自己生成令牌并将它们与时间戳一起存储。也许只有其中之一 - 寿命更长的短令牌。默认的 SMS 实现已经是短暂的,不适合手动输入。

【讨论】:

  • 感谢您的调查。我正在考虑在UserManager 中使用与GenerateChangePhoneNumberTokenAsyncVerifyChangePhoneNumberTokenAsync 类似的方法,但这会给我3 分钟的时间,所以我可能会复制Rfc6238AuthenticationService 代码并对其进行修改以指定时间步长。有人认为我不确定我是否将 _timespan 从 3 分钟更改为可以说 4 yours token 从现在起 4 小时或 8 小时后有效?您的回答有点令人困惑。你能澄清一下吗?
  • 我已经修改了你提到的那个 rfc6238 认证服务。我添加了用于指定时间步长的参数,但是因为这对我来说都是全新的,所以我不确定我是否正确地完成了所有操作。你能看一下吗? gist.github.com/Misiu/c2822de165e347ede71750ab20b6c12a
  • @Misiu 抱歉,我对这个算法了解不够。 Here 它实际上已经过验证,但我不知道 -2..+2 会发生什么。检查的唯一方法是编写单元测试并将DateTime.UtcNow here 替换为您可以更改以模拟更改时间的参数。
  • @Misiu 我已使用来自此answer 的代码来进行使用DateTime.UtcNow 的单元测试。 Part of my project - 供参考。还有this is how it is used in tests
  • 感谢您的宝贵时间和帮助。我已经测试了我的令牌实现。问题是算法 - 它使用时间窗口,而不是特定时间作为到期日期。如果我在午夜后几分钟生成令牌并将其有效期设置为 24 小时,则有效期为 2 天(直到当天和下一天结束),与 1 小时令牌相同,它们有效期至当前小时结束 + 一小时.我可能会编辑我的用户存储并添加 3 个额外的字段,一个用于令牌哈希,第二个用于令牌到期日期,第三个用于绑定数量。这样我就可以确定过期时间是正确的。
猜你喜欢
  • 1970-01-01
  • 2018-05-06
  • 2012-08-10
  • 2016-01-08
  • 1970-01-01
  • 2016-07-05
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
相关资源
最近更新 更多