ASP.NET Email Authentication Invalid Token

I am using the Asp.Net identifier. I systematically get an Invalid token error when I want to confirm new users with an email confirmation token.

Here is my WebApi user controller:

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);                     }
    }

To confirm the letter, I just do:

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

I do not do HttpUtility.UrlDecode because WebApi does this on its own.

And my user class user manager:

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"));            
        }
    }
}

Any idea? Many thanks

+4
source share
1 answer

I had the same problem, and I was able to solve it without implementing a custom provider based on machine keys .

UserTokenProvider, UserManager, DI . UserTokenProvider.

, , DpapiDataProtectionProvider - . DpapiDataProtectionProvider:

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

, , DpapiDataProtectionProvider, GUID, .

:

  • .
  • .

, ..

, DI ( Simple Injector) (- , ):

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

, -.

0

Source: https://habr.com/ru/post/1607669/


All Articles