0

I had problems with Identity ConfirmEmailAsync and always it returns Invalid Token. So I write a custom TokenProvider. at one side I have this Code:

//string confirmationToken = await userManager.GenerateEmailConfirmationTokenAsync(user);
string confirmationToken = await tokenProvider.GenerateAsyncEmail("mzpurposes", userManager, user);

string confirmationLink =
            $"{httpContext.HttpContext.Request.Scheme}://{httpContext.HttpContext.Request.Host}" +
            $"/account/confirmemail/{System.Web.HttpUtility.UrlEncode(user.Id)}" +
            $"/{System.Web.HttpUtility.UrlEncode(confirmationToken)}";

and at the other side in the ConfirmEmail page that Recieves UserID and Token as input Route parameters:

//IdentityResult result = await userManager.ConfirmEmailAsync(user, System.Web.HttpUtility.UrlDecode(Token));
    bool result =
        await tokenProvider.ValidateAsyncEmail("mzpurposes", System.Web.HttpUtility.UrlDecode(Token), userManager, user);
    if (result)   //.Succeeded)
    {
        Model = new UserConfirmModel() { Success = true };
    }
    else
    {
        Model = new UserConfirmModel() { Success = false };
    }

In the custom TokenProvider at the end of the method that creates the token I have:

var protectedBytes = protector.Protect(ms.ToArray());
        return Convert.ToBase64String(protectedBytes);

and at the begining of Validate Method there is:

 var unprotectedData = protector.Unprotect(Convert.FromBase64String(token));

every time I click the confirmation link and code reaches to this line I get this error:

The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters."}

Why do I recieve this error when I convert the bytes at the end of the method GenerateAsyncEmail to base64string? also in the startup class I have: services.AddDataProtection(); and I inject it to tokenprovider class.

I am Sure this is a bug in Blazor Serverside Component's input parameters.

mz1378
  • 1,957
  • 4
  • 20
  • 40
  • it looks like you are passing something different in `FromBase64String` than what you get after `ToBase64String` i guess you don't need to `UrlDecode` – Arjun Vachhani Oct 09 '19 at 12:23
  • I tested removing it before, but it didn't work too. I finally created a 6 digit random number and passed it to ConfirmEmail page that solved my issue. But It is not as secure as a token, I spend days to solve this in Blazor serverside preview 6(it is working in blazor client side preview 5) and tried every scenario with no success. – mz1378 Oct 10 '19 at 13:30

1 Answers1

0

You need to be aware of that you need to use an URL safe version of Base64 to avoid getting issues when you pass Base64 strings via querystrings

see How to achieve Base64 URL safe encoding in C#?

Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40