Asp.net 身份电子邮件验证令牌无法识别

Posted

技术标签:

【中文标题】Asp.net 身份电子邮件验证令牌无法识别【英文标题】:Asp.net Identity Email Verifcation Token Not Recognized 【发布时间】:2015-03-21 16:14:57 【问题描述】:

我们在 Web 表单应用程序中使用 Microsoft 的 Identity Framework v2.0。一切运作良好。我们决定在新帐户设置过程中添加电子邮件验证。如果我们在同一页面中创建令牌后验证令牌,我们就成功了。但是如果我们尝试在不同的页面中验证令牌,它就会失败。过程很简单:

    管理员通过提供用户的电子邮件和姓名来创建一个新帐户。 (我们不支持自行注册)。 用户单击他在电子邮件中获得的链接以验证电子邮件是否已收到。

这是创建电子邮件验证令牌的代码:

var manager = new UserManager();
var user = new ApplicationUser()  UserName = EmailAddress.Text, Email = EmailAddress.Text, FirstName = FirstName.Text, LastName = LastName.Text ;
IdentityResult result = manager.Create(user);
var provider = new DpapiDataProtectionProvider();
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("EmailConfirmation"))

    TokenLifespan = TimeSpan.FromHours(24)
;
var strToken = manager.GenerateEmailConfirmationToken(user.Id);
//IdentityResult validToken = manager.ConfirmEmail(user.Id, strToken);
strToken = HttpUtility.UrlEncode(strToken.ToString());

注意:如果我们取消注释以 //IdentityResult validToken... 开头的行,那么它会成功。

这是 VerifyEmail 页面上的代码:

string userid = Request.QueryString["id"].ToString();
string tokenReceived = Request.QueryString["token"].ToString();
//tokenReceived = HttpUtility.UrlDecode(tokenReceived);
ApplicationUser User = new ApplicationUser();
var manager = new UserManager();
User = manager.FindById(userid);
var provider = new DpapiDataProtectionProvider();
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("EmailConfirmation"))

    TokenLifespan = TimeSpan.FromHours(24)
;

IdentityResult validToken = manager.ConfirmEmail(User.Id, tokenReceived);

validToken 行在此文件中不成功。我已经验证了两个文件中的字符串 User.Id 和 tokenReceived 完全匹配,因此没有发生 URL 损坏。 (这就是我注释掉 UrlDecode 的原因,因为它似乎是由浏览器自动解码的——当我尝试解码时,它与编码前的字符串不是 100% 相同)。

所以我确定我们调用的是同一个方法 (ConfirmEmail),并且传递的两个参数是完全相同的字符串。我也知道一个令牌只能被验证一次,所以我不会在验证一次后重新使用它们。

欢迎提出任何想法。

【问题讨论】:

【参考方案1】:

我认为DpapiDataProtectionProvider 中的问题 - 如果您在创建和验证令牌时使用此类的相同实例,它会正常工作。

根据 VC2013 模板,您没有从 Owin Context 获得 UserManager 的任何原因?

【讨论】:

仅供参考:我意识到创建此类的全局实例会起作用,但我只是在创建时提供了一个应用程序名称: var provider = new DpapiDataProtectionProvider("MyApp");只要两个位置的应用名称相同,它现在就可以工作。 这是关于AppName 的一个好点,否则我认为它使用 guid 并且每次它都是一个新的 guid。而AppName 参数用作密码学密钥的一部分。

以上是关于Asp.net 身份电子邮件验证令牌无法识别的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用我的 JWT 进行身份验证,但我的名称声明在我的 ASP.NET Core 应用程序中无法识别

使用 ASP.NET 身份重置密码时令牌无效

无法使用 ASP.NET Core 从 JWT 令牌获取声明

在我的 ASP.NET Web API 中验证访问令牌

ASP.NET 核心 1.0。 Bearer Token,无法访问自定义声明

ASP.NET Core 中的 Jwt 令牌身份验证