ASP.NET身份电子邮件确认令牌无效

本文关键字:令牌 无效 确认 电子邮件 NET 身份 ASP | 更新日期: 2023-09-27 18:12:56

我使用Asp。净的身份。当我想用电子邮件确认令牌确认新用户时,系统地出现无效令牌错误。

这是我的WebApi用户控制器:
public class UsersController : ApiController
{
    private MyContext _db;
    private MyUserManager _userManager;
    private MyRoleManager _roleManager;

public UsersController()
{
    _db = new MyContext();
    _userManager = new MyUserManager(new UserStore<MyUser>(_db));
    _roleManager = new MyRoleManager(new RoleStore<IdentityRole>(_db));
}
//New user method
[HttpPost]
public async Task<HttpResponseMessage> Register([FromBody]PostUserModel userModel)
{
//New user code
...
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user.Id);
            var message = new IdentityMessage();
            message.Body = string.Format("Hi {0} !'r'nFollow this link to set your password : 'r'nhttps://www.mywebsite.com/admin/users/{1}/reset?token={2}", user.UserName, user.Id, HttpUtility.UrlEncode(token));
            message.Subject = "Confirm e-mail";
            message.Destination = user.Email;
            await _userManager.SendEmailAsync(user.Id, message.Subject, message.Body);
            return Request.CreateResponse(HttpStatusCode.OK, res);                     }
    }

确认邮件,我正在做:

var result = await _userManager.ConfirmEmailAsync(user.Id, token);

我没有做一个HttpUtility。因为WebApi是自己做的。

和我的自定义用户管理器类:

public class MyUserManager : UserManager<MyUser>
    {
        public MyUserManager(IUserStore<MyUser> store)
            : base(store)
        {            
            UserValidator = new UserValidator<MyUser>(this)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };
            // Configure validation logic for passwords
            PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = true,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true,
            };
            // Configure user lockout defaults
            UserLockoutEnabledByDefault = false;
            EmailService = new EmailService();
            SmsService = new SmsService();
            var dataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("MyApp");
            UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<MyUser>(dataProtectionProvider.Create("UserToken"));            
        }
    }
}

你知道吗?非常感谢

ASP.NET身份电子邮件确认令牌无效

我也遇到过同样的问题,我设法解决了它而没有实现基于机器密钥的自定义提供者

我已经在UserManager类中设置了UserTokenProvider,通过DI作为每个请求范围连接。因此,对于每个请求,我都创建了新的UserTokenProvider

当我检查源代码时,我注意到它在默认情况下使用DpapiDataProtectionProviderDpapiDataProtectionProvider使用的构造函数是:

public DpapiDataProtectionProvider()
  : this(Guid.NewGuid().ToString())
{
}

所以每次创建DpapiDataProtectionProvider时,它都会生成一个新的GUID,用作应用程序的名称。

有两种解决方法:

  1. 将其作为单例连接。
  2. 使用固定的应用名称

我决定使用第二个,因为单例解决方案会在应用程序池回收等方面再次中断。

所以现在我的DI注册(使用简单注入器)看起来像这样(仍然使用每个请求范围,即使它可能不是必要的):

container.Register<IUserTokenProvider<ApplicationUser, string>>(() =>
    new DataProtectorTokenProvider<ApplicationUser>
        (new DpapiDataProtectionProvider("MY APPLICATION NAME").Create("ASP.NET Identity"))
        {
            // all user tokens are only valid for 3 hours
            TokenLifespan = TimeSpan.FromHours(3)
        }, Lifestyle.Scoped);